mirror of
https://github.com/python/cpython.git
synced 2025-11-02 03:01:58 +00:00
Issue #24693: Changed some RuntimeError's in the zipfile module to more
appropriate types. Improved some error messages and debugging output.
This commit is contained in:
parent
b32e869eb1
commit
b0d497c072
4 changed files with 94 additions and 63 deletions
|
|
@ -147,10 +147,10 @@ ZipFile Objects
|
||||||
*compression* is the ZIP compression method to use when writing the archive,
|
*compression* is the ZIP compression method to use when writing the archive,
|
||||||
and should be :const:`ZIP_STORED`, :const:`ZIP_DEFLATED`,
|
and should be :const:`ZIP_STORED`, :const:`ZIP_DEFLATED`,
|
||||||
:const:`ZIP_BZIP2` or :const:`ZIP_LZMA`; unrecognized
|
:const:`ZIP_BZIP2` or :const:`ZIP_LZMA`; unrecognized
|
||||||
values will cause :exc:`RuntimeError` to be raised. If :const:`ZIP_DEFLATED`,
|
values will cause :exc:`NotImplementedError` to be raised. If :const:`ZIP_DEFLATED`,
|
||||||
:const:`ZIP_BZIP2` or :const:`ZIP_LZMA` is specified but the corresponding module
|
:const:`ZIP_BZIP2` or :const:`ZIP_LZMA` is specified but the corresponding module
|
||||||
(:mod:`zlib`, :mod:`bz2` or :mod:`lzma`) is not available, :exc:`RuntimeError`
|
(:mod:`zlib`, :mod:`bz2` or :mod:`lzma`) is not available, :exc:`RuntimeError`
|
||||||
is also raised. The default is :const:`ZIP_STORED`. If *allowZip64* is
|
is raised. The default is :const:`ZIP_STORED`. If *allowZip64* is
|
||||||
``True`` (the default) zipfile will create ZIP files that use the ZIP64
|
``True`` (the default) zipfile will create ZIP files that use the ZIP64
|
||||||
extensions when the zipfile is larger than 2 GiB. If it is false :mod:`zipfile`
|
extensions when the zipfile is larger than 2 GiB. If it is false :mod:`zipfile`
|
||||||
will raise an exception when the ZIP file would require ZIP64 extensions.
|
will raise an exception when the ZIP file would require ZIP64 extensions.
|
||||||
|
|
@ -179,6 +179,10 @@ ZipFile Objects
|
||||||
Added support for writing to unseekable streams.
|
Added support for writing to unseekable streams.
|
||||||
Added support for the ``'x'`` mode.
|
Added support for the ``'x'`` mode.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Previously, a plain :exc:`RuntimeError` was raised for unrecognized
|
||||||
|
compression values.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.close()
|
.. method:: ZipFile.close()
|
||||||
|
|
||||||
|
|
@ -211,7 +215,6 @@ ZipFile Objects
|
||||||
can be either the name of a file within the archive or a :class:`ZipInfo`
|
can be either the name of a file within the archive or a :class:`ZipInfo`
|
||||||
object. The *mode* parameter, if included, must be ``'r'`` (the default)
|
object. The *mode* parameter, if included, must be ``'r'`` (the default)
|
||||||
or ``'w'``. *pwd* is the password used to decrypt encrypted ZIP files.
|
or ``'w'``. *pwd* is the password used to decrypt encrypted ZIP files.
|
||||||
Calling :meth:`.open` on a closed ZipFile will raise a :exc:`RuntimeError`.
|
|
||||||
|
|
||||||
:meth:`~ZipFile.open` is also a context manager and therefore supports the
|
:meth:`~ZipFile.open` is also a context manager and therefore supports the
|
||||||
:keyword:`with` statement::
|
:keyword:`with` statement::
|
||||||
|
|
@ -230,7 +233,7 @@ ZipFile Objects
|
||||||
With ``mode='w'``, a writable file handle is returned, which supports the
|
With ``mode='w'``, a writable file handle is returned, which supports the
|
||||||
:meth:`~io.BufferedIOBase.write` method. While a writable file handle is open,
|
:meth:`~io.BufferedIOBase.write` method. While a writable file handle is open,
|
||||||
attempting to read or write other files in the ZIP file will raise a
|
attempting to read or write other files in the ZIP file will raise a
|
||||||
:exc:`RuntimeError`.
|
:exc:`ValueError`.
|
||||||
|
|
||||||
When writing a file, if the file size is not known in advance but may exceed
|
When writing a file, if the file size is not known in advance but may exceed
|
||||||
2 GiB, pass ``force_zip64=True`` to ensure that the header format is
|
2 GiB, pass ``force_zip64=True`` to ensure that the header format is
|
||||||
|
|
@ -252,6 +255,11 @@ ZipFile Objects
|
||||||
:meth:`open` can now be used to write files into the archive with the
|
:meth:`open` can now be used to write files into the archive with the
|
||||||
``mode='w'`` option.
|
``mode='w'`` option.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Calling :meth:`.open` on a closed ZipFile will raise a :exc:`ValueError`.
|
||||||
|
Previously, a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.extract(member, path=None, pwd=None)
|
.. method:: ZipFile.extract(member, path=None, pwd=None)
|
||||||
|
|
||||||
Extract a member from the archive to the current working directory; *member*
|
Extract a member from the archive to the current working directory; *member*
|
||||||
|
|
@ -272,6 +280,10 @@ ZipFile Objects
|
||||||
characters (``:``, ``<``, ``>``, ``|``, ``"``, ``?``, and ``*``)
|
characters (``:``, ``<``, ``>``, ``|``, ``"``, ``?``, and ``*``)
|
||||||
replaced by underscore (``_``).
|
replaced by underscore (``_``).
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Calling :meth:`extract` on a closed ZipFile will raise a
|
||||||
|
:exc:`ValueError`. Previously, a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.extractall(path=None, members=None, pwd=None)
|
.. method:: ZipFile.extractall(path=None, members=None, pwd=None)
|
||||||
|
|
||||||
|
|
@ -288,6 +300,10 @@ ZipFile Objects
|
||||||
dots ``".."``. This module attempts to prevent that.
|
dots ``".."``. This module attempts to prevent that.
|
||||||
See :meth:`extract` note.
|
See :meth:`extract` note.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Calling :meth:`extractall` on a closed ZipFile will raise a
|
||||||
|
:exc:`ValueError`. Previously, a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.printdir()
|
.. method:: ZipFile.printdir()
|
||||||
|
|
||||||
|
|
@ -305,18 +321,24 @@ ZipFile Objects
|
||||||
file in the archive, or a :class:`ZipInfo` object. The archive must be open for
|
file in the archive, or a :class:`ZipInfo` object. The archive must be open for
|
||||||
read or append. *pwd* is the password used for encrypted files and, if specified,
|
read or append. *pwd* is the password used for encrypted files and, if specified,
|
||||||
it will override the default password set with :meth:`setpassword`. Calling
|
it will override the default password set with :meth:`setpassword`. Calling
|
||||||
:meth:`read` on a closed ZipFile will raise a :exc:`RuntimeError`. Calling
|
|
||||||
:meth:`read` on a ZipFile that uses a compression method other than
|
:meth:`read` on a ZipFile that uses a compression method other than
|
||||||
:const:`ZIP_STORED`, :const:`ZIP_DEFLATED`, :const:`ZIP_BZIP2` or
|
:const:`ZIP_STORED`, :const:`ZIP_DEFLATED`, :const:`ZIP_BZIP2` or
|
||||||
:const:`ZIP_LZMA` will raise a :exc:`NotImplementedError`. An error will also
|
:const:`ZIP_LZMA` will raise a :exc:`NotImplementedError`. An error will also
|
||||||
be raised if the corresponding compression module is not available.
|
be raised if the corresponding compression module is not available.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Calling :meth:`read` on a closed ZipFile will raise a :exc:`ValueError`.
|
||||||
|
Previously, a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.testzip()
|
.. method:: ZipFile.testzip()
|
||||||
|
|
||||||
Read all the files in the archive and check their CRC's and file headers.
|
Read all the files in the archive and check their CRC's and file headers.
|
||||||
Return the name of the first bad file, or else return ``None``. Calling
|
Return the name of the first bad file, or else return ``None``.
|
||||||
:meth:`testzip` on a closed ZipFile will raise a :exc:`RuntimeError`.
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Calling :meth:`testfile` on a closed ZipFile will raise a
|
||||||
|
:exc:`ValueError`. Previously, a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.write(filename, arcname=None, compress_type=None)
|
.. method:: ZipFile.write(filename, arcname=None, compress_type=None)
|
||||||
|
|
@ -326,10 +348,7 @@ ZipFile Objects
|
||||||
letter and with leading path separators removed). If given, *compress_type*
|
letter and with leading path separators removed). If given, *compress_type*
|
||||||
overrides the value given for the *compression* parameter to the constructor for
|
overrides the value given for the *compression* parameter to the constructor for
|
||||||
the new entry.
|
the new entry.
|
||||||
The archive must be open with mode ``'w'``, ``'x'`` or ``'a'`` -- calling
|
The archive must be open with mode ``'w'``, ``'x'`` or ``'a'``.
|
||||||
:meth:`write` on a ZipFile created with mode ``'r'`` will raise a
|
|
||||||
:exc:`RuntimeError`. Calling :meth:`write` on a closed ZipFile will raise a
|
|
||||||
:exc:`RuntimeError`.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
@ -348,16 +367,19 @@ ZipFile Objects
|
||||||
If ``arcname`` (or ``filename``, if ``arcname`` is not given) contains a null
|
If ``arcname`` (or ``filename``, if ``arcname`` is not given) contains a null
|
||||||
byte, the name of the file in the archive will be truncated at the null byte.
|
byte, the name of the file in the archive will be truncated at the null byte.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Calling :meth:`write` on a ZipFile created with mode ``'r'`` or
|
||||||
|
a closed ZipFile will raise a :exc:`ValueError`. Previously,
|
||||||
|
a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.writestr(zinfo_or_arcname, data[, compress_type])
|
.. method:: ZipFile.writestr(zinfo_or_arcname, data[, compress_type])
|
||||||
|
|
||||||
Write the string *data* to the archive; *zinfo_or_arcname* is either the file
|
Write the string *data* to the archive; *zinfo_or_arcname* is either the file
|
||||||
name it will be given in the archive, or a :class:`ZipInfo` instance. If it's
|
name it will be given in the archive, or a :class:`ZipInfo` instance. If it's
|
||||||
an instance, at least the filename, date, and time must be given. If it's a
|
an instance, at least the filename, date, and time must be given. If it's a
|
||||||
name, the date and time is set to the current date and time.
|
name, the date and time is set to the current date and time.
|
||||||
The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'`` -- calling
|
The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'``.
|
||||||
:meth:`writestr` on a ZipFile created with mode ``'r'`` will raise a
|
|
||||||
:exc:`RuntimeError`. Calling :meth:`writestr` on a closed ZipFile will
|
|
||||||
raise a :exc:`RuntimeError`.
|
|
||||||
|
|
||||||
If given, *compress_type* overrides the value given for the *compression*
|
If given, *compress_type* overrides the value given for the *compression*
|
||||||
parameter to the constructor for the new entry, or in the *zinfo_or_arcname*
|
parameter to the constructor for the new entry, or in the *zinfo_or_arcname*
|
||||||
|
|
@ -373,6 +395,12 @@ ZipFile Objects
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
The *compress_type* argument.
|
The *compress_type* argument.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Calling :meth:`writestr` on a ZipFile created with mode ``'r'`` or
|
||||||
|
a closed ZipFile will raise a :exc:`ValueError`. Previously,
|
||||||
|
a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
|
||||||
The following data attributes are also available:
|
The following data attributes are also available:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -449,15 +449,15 @@ class StoredTestsWithSourceFile(AbstractTestsWithSourceFile,
|
||||||
|
|
||||||
def test_write_to_readonly(self):
|
def test_write_to_readonly(self):
|
||||||
"""Check that trying to call write() on a readonly ZipFile object
|
"""Check that trying to call write() on a readonly ZipFile object
|
||||||
raises a RuntimeError."""
|
raises a ValueError."""
|
||||||
with zipfile.ZipFile(TESTFN2, mode="w") as zipfp:
|
with zipfile.ZipFile(TESTFN2, mode="w") as zipfp:
|
||||||
zipfp.writestr("somefile.txt", "bogus")
|
zipfp.writestr("somefile.txt", "bogus")
|
||||||
|
|
||||||
with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
|
with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
|
||||||
self.assertRaises(RuntimeError, zipfp.write, TESTFN)
|
self.assertRaises(ValueError, zipfp.write, TESTFN)
|
||||||
|
|
||||||
with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
|
with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
zipfp.open(TESTFN, mode='w')
|
zipfp.open(TESTFN, mode='w')
|
||||||
|
|
||||||
def test_add_file_before_1980(self):
|
def test_add_file_before_1980(self):
|
||||||
|
|
@ -1210,27 +1210,27 @@ class OtherTests(unittest.TestCase):
|
||||||
fp.write("short file")
|
fp.write("short file")
|
||||||
self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN)
|
self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN)
|
||||||
|
|
||||||
def test_closed_zip_raises_RuntimeError(self):
|
def test_closed_zip_raises_ValueError(self):
|
||||||
"""Verify that testzip() doesn't swallow inappropriate exceptions."""
|
"""Verify that testzip() doesn't swallow inappropriate exceptions."""
|
||||||
data = io.BytesIO()
|
data = io.BytesIO()
|
||||||
with zipfile.ZipFile(data, mode="w") as zipf:
|
with zipfile.ZipFile(data, mode="w") as zipf:
|
||||||
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
|
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
|
||||||
|
|
||||||
# This is correct; calling .read on a closed ZipFile should raise
|
# This is correct; calling .read on a closed ZipFile should raise
|
||||||
# a RuntimeError, and so should calling .testzip. An earlier
|
# a ValueError, and so should calling .testzip. An earlier
|
||||||
# version of .testzip would swallow this exception (and any other)
|
# version of .testzip would swallow this exception (and any other)
|
||||||
# and report that the first file in the archive was corrupt.
|
# and report that the first file in the archive was corrupt.
|
||||||
self.assertRaises(RuntimeError, zipf.read, "foo.txt")
|
self.assertRaises(ValueError, zipf.read, "foo.txt")
|
||||||
self.assertRaises(RuntimeError, zipf.open, "foo.txt")
|
self.assertRaises(ValueError, zipf.open, "foo.txt")
|
||||||
self.assertRaises(RuntimeError, zipf.testzip)
|
self.assertRaises(ValueError, zipf.testzip)
|
||||||
self.assertRaises(RuntimeError, zipf.writestr, "bogus.txt", "bogus")
|
self.assertRaises(ValueError, zipf.writestr, "bogus.txt", "bogus")
|
||||||
with open(TESTFN, 'w') as f:
|
with open(TESTFN, 'w') as f:
|
||||||
f.write('zipfile test data')
|
f.write('zipfile test data')
|
||||||
self.assertRaises(RuntimeError, zipf.write, TESTFN)
|
self.assertRaises(ValueError, zipf.write, TESTFN)
|
||||||
|
|
||||||
def test_bad_constructor_mode(self):
|
def test_bad_constructor_mode(self):
|
||||||
"""Check that bad modes passed to ZipFile constructor are caught."""
|
"""Check that bad modes passed to ZipFile constructor are caught."""
|
||||||
self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q")
|
self.assertRaises(ValueError, zipfile.ZipFile, TESTFN, "q")
|
||||||
|
|
||||||
def test_bad_open_mode(self):
|
def test_bad_open_mode(self):
|
||||||
"""Check that bad modes passed to ZipFile.open are caught."""
|
"""Check that bad modes passed to ZipFile.open are caught."""
|
||||||
|
|
@ -1240,10 +1240,10 @@ class OtherTests(unittest.TestCase):
|
||||||
with zipfile.ZipFile(TESTFN, mode="r") as zipf:
|
with zipfile.ZipFile(TESTFN, mode="r") as zipf:
|
||||||
# read the data to make sure the file is there
|
# read the data to make sure the file is there
|
||||||
zipf.read("foo.txt")
|
zipf.read("foo.txt")
|
||||||
self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q")
|
self.assertRaises(ValueError, zipf.open, "foo.txt", "q")
|
||||||
# universal newlines support is removed
|
# universal newlines support is removed
|
||||||
self.assertRaises(RuntimeError, zipf.open, "foo.txt", "U")
|
self.assertRaises(ValueError, zipf.open, "foo.txt", "U")
|
||||||
self.assertRaises(RuntimeError, zipf.open, "foo.txt", "rU")
|
self.assertRaises(ValueError, zipf.open, "foo.txt", "rU")
|
||||||
|
|
||||||
def test_read0(self):
|
def test_read0(self):
|
||||||
"""Check that calling read(0) on a ZipExtFile object returns an empty
|
"""Check that calling read(0) on a ZipExtFile object returns an empty
|
||||||
|
|
@ -1266,7 +1266,7 @@ class OtherTests(unittest.TestCase):
|
||||||
def test_bad_compression_mode(self):
|
def test_bad_compression_mode(self):
|
||||||
"""Check that bad compression methods passed to ZipFile.open are
|
"""Check that bad compression methods passed to ZipFile.open are
|
||||||
caught."""
|
caught."""
|
||||||
self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1)
|
self.assertRaises(NotImplementedError, zipfile.ZipFile, TESTFN, "w", -1)
|
||||||
|
|
||||||
def test_unsupported_compression(self):
|
def test_unsupported_compression(self):
|
||||||
# data is declared as shrunk, but actually deflated
|
# data is declared as shrunk, but actually deflated
|
||||||
|
|
@ -1423,15 +1423,15 @@ class OtherTests(unittest.TestCase):
|
||||||
with zipf.open('foo', mode='w') as w2:
|
with zipf.open('foo', mode='w') as w2:
|
||||||
w2.write(msg1)
|
w2.write(msg1)
|
||||||
with zipf.open('bar', mode='w') as w1:
|
with zipf.open('bar', mode='w') as w1:
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
zipf.open('handle', mode='w')
|
zipf.open('handle', mode='w')
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
zipf.open('foo', mode='r')
|
zipf.open('foo', mode='r')
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
zipf.writestr('str', 'abcde')
|
zipf.writestr('str', 'abcde')
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
zipf.write(__file__, 'file')
|
zipf.write(__file__, 'file')
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
zipf.close()
|
zipf.close()
|
||||||
w1.write(msg2)
|
w1.write(msg2)
|
||||||
with zipf.open('baz', mode='w') as w2:
|
with zipf.open('baz', mode='w') as w2:
|
||||||
|
|
|
||||||
|
|
@ -449,7 +449,7 @@ class ZipInfo (object):
|
||||||
elif ln == 0:
|
elif ln == 0:
|
||||||
counts = ()
|
counts = ()
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Corrupt extra field %s"%(ln,))
|
raise BadZipFile("Corrupt extra field %04x (size=%d)" % (tp, ln))
|
||||||
|
|
||||||
idx = 0
|
idx = 0
|
||||||
|
|
||||||
|
|
@ -654,7 +654,7 @@ def _check_compression(compression):
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"Compression requires the (missing) lzma module")
|
"Compression requires the (missing) lzma module")
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("That compression method is not supported")
|
raise NotImplementedError("That compression method is not supported")
|
||||||
|
|
||||||
|
|
||||||
def _get_compressor(compress_type):
|
def _get_compressor(compress_type):
|
||||||
|
|
@ -697,7 +697,7 @@ class _SharedFile:
|
||||||
def read(self, n=-1):
|
def read(self, n=-1):
|
||||||
with self._lock:
|
with self._lock:
|
||||||
if self._writing():
|
if self._writing():
|
||||||
raise RuntimeError("Can't read from the ZIP file while there "
|
raise ValueError("Can't read from the ZIP file while there "
|
||||||
"is an open writing handle on it. "
|
"is an open writing handle on it. "
|
||||||
"Close the writing handle before trying to read.")
|
"Close the writing handle before trying to read.")
|
||||||
self._file.seek(self._pos)
|
self._file.seek(self._pos)
|
||||||
|
|
@ -1055,7 +1055,7 @@ class ZipFile:
|
||||||
"""Open the ZIP file with mode read 'r', write 'w', exclusive create 'x',
|
"""Open the ZIP file with mode read 'r', write 'w', exclusive create 'x',
|
||||||
or append 'a'."""
|
or append 'a'."""
|
||||||
if mode not in ('r', 'w', 'x', 'a'):
|
if mode not in ('r', 'w', 'x', 'a'):
|
||||||
raise RuntimeError("ZipFile requires mode 'r', 'w', 'x', or 'a'")
|
raise ValueError("ZipFile requires mode 'r', 'w', 'x', or 'a'")
|
||||||
|
|
||||||
_check_compression(compression)
|
_check_compression(compression)
|
||||||
|
|
||||||
|
|
@ -1129,7 +1129,7 @@ class ZipFile:
|
||||||
self._didModify = True
|
self._didModify = True
|
||||||
self.start_dir = self.fp.tell()
|
self.start_dir = self.fp.tell()
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Mode must be 'r', 'w', 'x', or 'a'")
|
raise ValueError("Mode must be 'r', 'w', 'x', or 'a'")
|
||||||
except:
|
except:
|
||||||
fp = self.fp
|
fp = self.fp
|
||||||
self.fp = None
|
self.fp = None
|
||||||
|
|
@ -1277,7 +1277,7 @@ class ZipFile:
|
||||||
def setpassword(self, pwd):
|
def setpassword(self, pwd):
|
||||||
"""Set default password for encrypted files."""
|
"""Set default password for encrypted files."""
|
||||||
if pwd and not isinstance(pwd, bytes):
|
if pwd and not isinstance(pwd, bytes):
|
||||||
raise TypeError("pwd: expected bytes, got %s" % type(pwd))
|
raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__)
|
||||||
if pwd:
|
if pwd:
|
||||||
self.pwd = pwd
|
self.pwd = pwd
|
||||||
else:
|
else:
|
||||||
|
|
@ -1291,7 +1291,7 @@ class ZipFile:
|
||||||
@comment.setter
|
@comment.setter
|
||||||
def comment(self, comment):
|
def comment(self, comment):
|
||||||
if not isinstance(comment, bytes):
|
if not isinstance(comment, bytes):
|
||||||
raise TypeError("comment: expected bytes, got %s" % type(comment))
|
raise TypeError("comment: expected bytes, got %s" % type(comment).__name__)
|
||||||
# check for valid comment length
|
# check for valid comment length
|
||||||
if len(comment) > ZIP_MAX_COMMENT:
|
if len(comment) > ZIP_MAX_COMMENT:
|
||||||
import warnings
|
import warnings
|
||||||
|
|
@ -1323,13 +1323,13 @@ class ZipFile:
|
||||||
instance for name, with zinfo.file_size set.
|
instance for name, with zinfo.file_size set.
|
||||||
"""
|
"""
|
||||||
if mode not in {"r", "w"}:
|
if mode not in {"r", "w"}:
|
||||||
raise RuntimeError('open() requires mode "r" or "w"')
|
raise ValueError('open() requires mode "r" or "w"')
|
||||||
if pwd and not isinstance(pwd, bytes):
|
if pwd and not isinstance(pwd, bytes):
|
||||||
raise TypeError("pwd: expected bytes, got %s" % type(pwd))
|
raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__)
|
||||||
if pwd and (mode == "w"):
|
if pwd and (mode == "w"):
|
||||||
raise ValueError("pwd is only supported for reading files")
|
raise ValueError("pwd is only supported for reading files")
|
||||||
if not self.fp:
|
if not self.fp:
|
||||||
raise RuntimeError(
|
raise ValueError(
|
||||||
"Attempt to use ZIP archive that was already closed")
|
"Attempt to use ZIP archive that was already closed")
|
||||||
|
|
||||||
# Make sure we have an info object
|
# Make sure we have an info object
|
||||||
|
|
@ -1347,7 +1347,7 @@ class ZipFile:
|
||||||
return self._open_to_write(zinfo, force_zip64=force_zip64)
|
return self._open_to_write(zinfo, force_zip64=force_zip64)
|
||||||
|
|
||||||
if self._writing:
|
if self._writing:
|
||||||
raise RuntimeError("Can't read from the ZIP file while there "
|
raise ValueError("Can't read from the ZIP file while there "
|
||||||
"is an open writing handle on it. "
|
"is an open writing handle on it. "
|
||||||
"Close the writing handle before trying to read.")
|
"Close the writing handle before trying to read.")
|
||||||
|
|
||||||
|
|
@ -1394,7 +1394,7 @@ class ZipFile:
|
||||||
if not pwd:
|
if not pwd:
|
||||||
pwd = self.pwd
|
pwd = self.pwd
|
||||||
if not pwd:
|
if not pwd:
|
||||||
raise RuntimeError("File %s is encrypted, password "
|
raise RuntimeError("File %r is encrypted, password "
|
||||||
"required for extraction" % name)
|
"required for extraction" % name)
|
||||||
|
|
||||||
zd = _ZipDecrypter(pwd)
|
zd = _ZipDecrypter(pwd)
|
||||||
|
|
@ -1412,7 +1412,7 @@ class ZipFile:
|
||||||
# compare against the CRC otherwise
|
# compare against the CRC otherwise
|
||||||
check_byte = (zinfo.CRC >> 24) & 0xff
|
check_byte = (zinfo.CRC >> 24) & 0xff
|
||||||
if h[11] != check_byte:
|
if h[11] != check_byte:
|
||||||
raise RuntimeError("Bad password for file", name)
|
raise RuntimeError("Bad password for file %r" % name)
|
||||||
|
|
||||||
return ZipExtFile(zef_file, mode, zinfo, zd, True)
|
return ZipExtFile(zef_file, mode, zinfo, zd, True)
|
||||||
except:
|
except:
|
||||||
|
|
@ -1426,9 +1426,9 @@ class ZipFile:
|
||||||
"the ZIP file."
|
"the ZIP file."
|
||||||
)
|
)
|
||||||
if self._writing:
|
if self._writing:
|
||||||
raise RuntimeError("Can't write to the ZIP file while there is "
|
raise ValueError("Can't write to the ZIP file while there is "
|
||||||
"another write handle open on it. "
|
"another write handle open on it. "
|
||||||
"Close the first handle before opening another.")
|
"Close the first handle before opening another.")
|
||||||
|
|
||||||
# Sizes and CRC are overwritten with correct data after processing the file
|
# Sizes and CRC are overwritten with correct data after processing the file
|
||||||
if not hasattr(zinfo, 'file_size'):
|
if not hasattr(zinfo, 'file_size'):
|
||||||
|
|
@ -1548,9 +1548,9 @@ class ZipFile:
|
||||||
import warnings
|
import warnings
|
||||||
warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3)
|
warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3)
|
||||||
if self.mode not in ('w', 'x', 'a'):
|
if self.mode not in ('w', 'x', 'a'):
|
||||||
raise RuntimeError("write() requires mode 'w', 'x', or 'a'")
|
raise ValueError("write() requires mode 'w', 'x', or 'a'")
|
||||||
if not self.fp:
|
if not self.fp:
|
||||||
raise RuntimeError(
|
raise ValueError(
|
||||||
"Attempt to write ZIP archive that was already closed")
|
"Attempt to write ZIP archive that was already closed")
|
||||||
_check_compression(zinfo.compress_type)
|
_check_compression(zinfo.compress_type)
|
||||||
if not self._allowZip64:
|
if not self._allowZip64:
|
||||||
|
|
@ -1569,10 +1569,10 @@ class ZipFile:
|
||||||
"""Put the bytes from filename into the archive under the name
|
"""Put the bytes from filename into the archive under the name
|
||||||
arcname."""
|
arcname."""
|
||||||
if not self.fp:
|
if not self.fp:
|
||||||
raise RuntimeError(
|
raise ValueError(
|
||||||
"Attempt to write to ZIP archive that was already closed")
|
"Attempt to write to ZIP archive that was already closed")
|
||||||
if self._writing:
|
if self._writing:
|
||||||
raise RuntimeError(
|
raise ValueError(
|
||||||
"Can't write to ZIP archive while an open writing handle exists"
|
"Can't write to ZIP archive while an open writing handle exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1628,10 +1628,10 @@ class ZipFile:
|
||||||
zinfo = zinfo_or_arcname
|
zinfo = zinfo_or_arcname
|
||||||
|
|
||||||
if not self.fp:
|
if not self.fp:
|
||||||
raise RuntimeError(
|
raise ValueError(
|
||||||
"Attempt to write to ZIP archive that was already closed")
|
"Attempt to write to ZIP archive that was already closed")
|
||||||
if self._writing:
|
if self._writing:
|
||||||
raise RuntimeError(
|
raise ValueError(
|
||||||
"Can't write to ZIP archive while an open writing handle exists."
|
"Can't write to ZIP archive while an open writing handle exists."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1654,9 +1654,9 @@ class ZipFile:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._writing:
|
if self._writing:
|
||||||
raise RuntimeError("Can't close the ZIP file while there is "
|
raise ValueError("Can't close the ZIP file while there is "
|
||||||
"an open writing handle on it. "
|
"an open writing handle on it. "
|
||||||
"Close the writing handle before closing the zip.")
|
"Close the writing handle before closing the zip.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.mode in ('w', 'x', 'a') and self._didModify: # write ending records
|
if self.mode in ('w', 'x', 'a') and self._didModify: # write ending records
|
||||||
|
|
@ -1803,7 +1803,7 @@ class PyZipFile(ZipFile):
|
||||||
if filterfunc and not filterfunc(pathname):
|
if filterfunc and not filterfunc(pathname):
|
||||||
if self.debug:
|
if self.debug:
|
||||||
label = 'path' if os.path.isdir(pathname) else 'file'
|
label = 'path' if os.path.isdir(pathname) else 'file'
|
||||||
print('%s "%s" skipped by filterfunc' % (label, pathname))
|
print('%s %r skipped by filterfunc' % (label, pathname))
|
||||||
return
|
return
|
||||||
dir, name = os.path.split(pathname)
|
dir, name = os.path.split(pathname)
|
||||||
if os.path.isdir(pathname):
|
if os.path.isdir(pathname):
|
||||||
|
|
@ -1834,7 +1834,7 @@ class PyZipFile(ZipFile):
|
||||||
elif ext == ".py":
|
elif ext == ".py":
|
||||||
if filterfunc and not filterfunc(path):
|
if filterfunc and not filterfunc(path):
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print('file "%s" skipped by filterfunc' % path)
|
print('file %r skipped by filterfunc' % path)
|
||||||
continue
|
continue
|
||||||
fname, arcname = self._get_codename(path[0:-3],
|
fname, arcname = self._get_codename(path[0:-3],
|
||||||
basename)
|
basename)
|
||||||
|
|
@ -1851,7 +1851,7 @@ class PyZipFile(ZipFile):
|
||||||
if ext == ".py":
|
if ext == ".py":
|
||||||
if filterfunc and not filterfunc(path):
|
if filterfunc and not filterfunc(path):
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print('file "%s" skipped by filterfunc' % path)
|
print('file %r skipped by filterfunc' % path)
|
||||||
continue
|
continue
|
||||||
fname, arcname = self._get_codename(path[0:-3],
|
fname, arcname = self._get_codename(path[0:-3],
|
||||||
basename)
|
basename)
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #24693: Changed some RuntimeError's in the zipfile module to more
|
||||||
|
appropriate types. Improved some error messages and debugging output.
|
||||||
|
|
||||||
- Issue #17909: ``json.load`` and ``json.loads`` now support binary input
|
- Issue #17909: ``json.load`` and ``json.loads`` now support binary input
|
||||||
encoded as UTF-8, UTF-16 or UTF-32. Patch by Serhiy Storchaka.
|
encoded as UTF-8, UTF-16 or UTF-32. Patch by Serhiy Storchaka.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue