Merge pull request #877 from JackDandy/feature/UpdateRarfile

Update rarfile to 3.0 (3e54b22).
This commit is contained in:
JackDandy 2017-02-01 04:10:37 +00:00 committed by GitHub
commit f3822e6107
2 changed files with 45 additions and 25 deletions

View file

@ -18,6 +18,7 @@
* Update moment.js 2.15.1 to 2.17.1
* Update PNotify library 2.1.0 to 3.0.0 (175af26)
* Update profilehooks 1.8.2.dev0 (ee3f1a8) to 1.9.0 (de7d59b)
* Update rarfile to 3.0 (3e54b22)
[develop changelog]

View file

@ -140,8 +140,12 @@ except ImportError:
_have_crypto = 0
try:
from pyblake2 import blake2s
_have_blake2 = True
try:
from hashlib import blake2s
_have_blake2 = True
except ImportError:
from pyblake2 import blake2s
_have_blake2 = True
except ImportError:
_have_blake2 = False
@ -380,8 +384,8 @@ UTC = timezone(timedelta(0), 'UTC')
BSIZE = 32 * 1024
def _get_rar_version(xfile):
'''Check quickly whether file is rar archive.
'''
"""Check quickly whether file is rar archive.
"""
with XFile(xfile) as fd:
buf = fd.read(len(RAR5_ID))
if buf.startswith(RAR_ID):
@ -395,8 +399,8 @@ def _get_rar_version(xfile):
##
def is_rarfile(xfile):
'''Check quickly whether file is rar archive.
'''
"""Check quickly whether file is rar archive.
"""
return _get_rar_version(xfile) > 0
class Error(Exception):
@ -473,7 +477,7 @@ class RarCannotExec(RarExecError):
class RarInfo(object):
r'''An entry in rar archive.
r"""An entry in rar archive.
RAR3 extended timestamps are :class:`datetime.datetime` objects without timezone.
RAR5 extended timestamps are :class:`datetime.datetime` objects with UTC timezone.
@ -566,7 +570,7 @@ class RarInfo(object):
volume_file
Volume file name, where file starts.
'''
"""
# zipfile-compatible fields
filename = None
@ -616,8 +620,8 @@ class RarInfo(object):
class RarFile(object):
'''Parse RAR structure, provide access to files in archive.
'''
"""Parse RAR structure, provide access to files in archive.
"""
#: Archive comment. Unicode string or None.
comment = None
@ -662,13 +666,16 @@ class RarFile(object):
self._parse()
def __enter__(self):
"""Open context."""
return self
def __exit__(self, typ, value, traceback):
"""Exit context"""
self.close()
def setpassword(self, password):
'''Sets the password to use when extracting.'''
"""Sets the password to use when extracting.
"""
self._password = password
if self._file_parser:
if self._file_parser.has_header_encryption():
@ -679,33 +686,35 @@ class RarFile(object):
self._file_parser.setpassword(self._password)
def needs_password(self):
'''Returns True if any archive entries require password for extraction.'''
"""Returns True if any archive entries require password for extraction.
"""
return self._file_parser.needs_password()
def namelist(self):
'''Return list of filenames in archive.'''
"""Return list of filenames in archive.
"""
return [f.filename for f in self.infolist()]
def infolist(self):
'''Return RarInfo objects for all files/directories in archive.'''
"""Return RarInfo objects for all files/directories in archive.
"""
return self._file_parser.infolist()
def volumelist(self):
'''Returns filenames of archive volumes.
"""Returns filenames of archive volumes.
In case of single-volume archive, the list contains
just the name of main archive file.
'''
"""
return self._file_parser.volumelist()
def getinfo(self, fname):
'''Return RarInfo for file.
'''
"""Return RarInfo for file.
"""
return self._file_parser.getinfo(fname)
def open(self, fname, mode='r', psw=None):
'''Returns file-like object (:class:`RarExtFile`),
from where the data can be read.
"""Returns file-like object (:class:`RarExtFile`) from where the data can be read.
The object implements :class:`io.RawIOBase` interface, so it can
be further wrapped with :class:`io.BufferedReader`
@ -726,7 +735,7 @@ class RarFile(object):
must be 'r'
psw
password to use for extracting.
'''
"""
if mode != 'r':
raise NotImplementedError("RarFile.open() supports only mode=r")
@ -823,8 +832,7 @@ class RarFile(object):
check_returncode(p, output)
def strerror(self):
"""Return error string if parsing failed,
or None if no problems.
"""Return error string if parsing failed or None if no problems.
"""
if not self._file_parser:
return "Not a RAR file"
@ -935,9 +943,14 @@ class CommonParser(object):
"""
return self._info_list
def getinfo(self, fname):
def getinfo(self, member):
"""Return RarInfo for filename
"""
if isinstance(member, RarInfo):
fname = member.filename
else:
fname = member
# accept both ways here
if PATH_SEP == '/':
fname2 = fname.replace("\\", "/")
@ -1951,6 +1964,8 @@ class RarExtFile(RawIOBase):
name = None
def __init__(self, parser, inf):
"""Open archive entry.
"""
super(RarExtFile, self).__init__()
# standard io.* properties
@ -2100,7 +2115,8 @@ class RarExtFile(RawIOBase):
def writable(self):
"""Returns False.
Writing is not supported."""
Writing is not supported.
"""
return False
def seekable(self):
@ -2856,6 +2872,7 @@ def hmac_sha256(key, data):
return HMAC(key, data, sha256).digest()
def membuf_tempfile(memfile):
"""Write in-memory file object to real file."""
memfile.seek(0, 0)
tmpfd, tmpname = mkstemp(suffix='.rar')
@ -2875,6 +2892,8 @@ def membuf_tempfile(memfile):
return tmpname
class XTempFile(object):
"""Real file for archive.
"""
__slots__ = ('_tmpfile', '_filename')
def __init__(self, rarfile):