Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b0d497c

Browse files
Issue #24693: Changed some RuntimeError's in the zipfile module to more
appropriate types. Improved some error messages and debugging output.
1 parent b32e869 commit b0d497c

4 files changed

Lines changed: 94 additions & 63 deletions

File tree

Doc/library/zipfile.rst

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ ZipFile Objects
147147
*compression* is the ZIP compression method to use when writing the archive,
148148
and should be :const:`ZIP_STORED`, :const:`ZIP_DEFLATED`,
149149
:const:`ZIP_BZIP2` or :const:`ZIP_LZMA`; unrecognized
150-
values will cause :exc:`RuntimeError` to be raised. If :const:`ZIP_DEFLATED`,
150+
values will cause :exc:`NotImplementedError` to be raised. If :const:`ZIP_DEFLATED`,
151151
:const:`ZIP_BZIP2` or :const:`ZIP_LZMA` is specified but the corresponding module
152152
(:mod:`zlib`, :mod:`bz2` or :mod:`lzma`) is not available, :exc:`RuntimeError`
153-
is also raised. The default is :const:`ZIP_STORED`. If *allowZip64* is
153+
is raised. The default is :const:`ZIP_STORED`. If *allowZip64* is
154154
``True`` (the default) zipfile will create ZIP files that use the ZIP64
155155
extensions when the zipfile is larger than 2 GiB. If it is false :mod:`zipfile`
156156
will raise an exception when the ZIP file would require ZIP64 extensions.
@@ -179,6 +179,10 @@ ZipFile Objects
179179
Added support for writing to unseekable streams.
180180
Added support for the ``'x'`` mode.
181181

182+
.. versionchanged:: 3.6
183+
Previously, a plain :exc:`RuntimeError` was raised for unrecognized
184+
compression values.
185+
182186

183187
.. method:: ZipFile.close()
184188

@@ -211,7 +215,6 @@ ZipFile Objects
211215
can be either the name of a file within the archive or a :class:`ZipInfo`
212216
object. The *mode* parameter, if included, must be ``'r'`` (the default)
213217
or ``'w'``. *pwd* is the password used to decrypt encrypted ZIP files.
214-
Calling :meth:`.open` on a closed ZipFile will raise a :exc:`RuntimeError`.
215218

216219
:meth:`~ZipFile.open` is also a context manager and therefore supports the
217220
:keyword:`with` statement::
@@ -230,7 +233,7 @@ ZipFile Objects
230233
With ``mode='w'``, a writable file handle is returned, which supports the
231234
:meth:`~io.BufferedIOBase.write` method. While a writable file handle is open,
232235
attempting to read or write other files in the ZIP file will raise a
233-
:exc:`RuntimeError`.
236+
:exc:`ValueError`.
234237

235238
When writing a file, if the file size is not known in advance but may exceed
236239
2 GiB, pass ``force_zip64=True`` to ensure that the header format is
@@ -252,6 +255,11 @@ ZipFile Objects
252255
:meth:`open` can now be used to write files into the archive with the
253256
``mode='w'`` option.
254257

258+
.. versionchanged:: 3.6
259+
Calling :meth:`.open` on a closed ZipFile will raise a :exc:`ValueError`.
260+
Previously, a :exc:`RuntimeError` was raised.
261+
262+
255263
.. method:: ZipFile.extract(member, path=None, pwd=None)
256264

257265
Extract a member from the archive to the current working directory; *member*
@@ -272,6 +280,10 @@ ZipFile Objects
272280
characters (``:``, ``<``, ``>``, ``|``, ``"``, ``?``, and ``*``)
273281
replaced by underscore (``_``).
274282

283+
.. versionchanged:: 3.6
284+
Calling :meth:`extract` on a closed ZipFile will raise a
285+
:exc:`ValueError`. Previously, a :exc:`RuntimeError` was raised.
286+
275287

276288
.. method:: ZipFile.extractall(path=None, members=None, pwd=None)
277289

@@ -288,6 +300,10 @@ ZipFile Objects
288300
dots ``".."``. This module attempts to prevent that.
289301
See :meth:`extract` note.
290302

303+
.. versionchanged:: 3.6
304+
Calling :meth:`extractall` on a closed ZipFile will raise a
305+
:exc:`ValueError`. Previously, a :exc:`RuntimeError` was raised.
306+
291307

292308
.. method:: ZipFile.printdir()
293309

@@ -305,18 +321,24 @@ ZipFile Objects
305321
file in the archive, or a :class:`ZipInfo` object. The archive must be open for
306322
read or append. *pwd* is the password used for encrypted files and, if specified,
307323
it will override the default password set with :meth:`setpassword`. Calling
308-
:meth:`read` on a closed ZipFile will raise a :exc:`RuntimeError`. Calling
309324
:meth:`read` on a ZipFile that uses a compression method other than
310325
:const:`ZIP_STORED`, :const:`ZIP_DEFLATED`, :const:`ZIP_BZIP2` or
311326
:const:`ZIP_LZMA` will raise a :exc:`NotImplementedError`. An error will also
312327
be raised if the corresponding compression module is not available.
313328

329+
.. versionchanged:: 3.6
330+
Calling :meth:`read` on a closed ZipFile will raise a :exc:`ValueError`.
331+
Previously, a :exc:`RuntimeError` was raised.
332+
314333

315334
.. method:: ZipFile.testzip()
316335

317336
Read all the files in the archive and check their CRC's and file headers.
318-
Return the name of the first bad file, or else return ``None``. Calling
319-
:meth:`testzip` on a closed ZipFile will raise a :exc:`RuntimeError`.
337+
Return the name of the first bad file, or else return ``None``.
338+
339+
.. versionchanged:: 3.6
340+
Calling :meth:`testfile` on a closed ZipFile will raise a
341+
:exc:`ValueError`. Previously, a :exc:`RuntimeError` was raised.
320342

321343

322344
.. method:: ZipFile.write(filename, arcname=None, compress_type=None)
@@ -326,10 +348,7 @@ ZipFile Objects
326348
letter and with leading path separators removed). If given, *compress_type*
327349
overrides the value given for the *compression* parameter to the constructor for
328350
the new entry.
329-
The archive must be open with mode ``'w'``, ``'x'`` or ``'a'`` -- calling
330-
:meth:`write` on a ZipFile created with mode ``'r'`` will raise a
331-
:exc:`RuntimeError`. Calling :meth:`write` on a closed ZipFile will raise a
332-
:exc:`RuntimeError`.
351+
The archive must be open with mode ``'w'``, ``'x'`` or ``'a'``.
333352

334353
.. note::
335354

@@ -348,16 +367,19 @@ ZipFile Objects
348367
If ``arcname`` (or ``filename``, if ``arcname`` is not given) contains a null
349368
byte, the name of the file in the archive will be truncated at the null byte.
350369

370+
.. versionchanged:: 3.6
371+
Calling :meth:`write` on a ZipFile created with mode ``'r'`` or
372+
a closed ZipFile will raise a :exc:`ValueError`. Previously,
373+
a :exc:`RuntimeError` was raised.
374+
375+
351376
.. method:: ZipFile.writestr(zinfo_or_arcname, data[, compress_type])
352377

353378
Write the string *data* to the archive; *zinfo_or_arcname* is either the file
354379
name it will be given in the archive, or a :class:`ZipInfo` instance. If it's
355380
an instance, at least the filename, date, and time must be given. If it's a
356381
name, the date and time is set to the current date and time.
357-
The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'`` -- calling
358-
:meth:`writestr` on a ZipFile created with mode ``'r'`` will raise a
359-
:exc:`RuntimeError`. Calling :meth:`writestr` on a closed ZipFile will
360-
raise a :exc:`RuntimeError`.
382+
The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'``.
361383

362384
If given, *compress_type* overrides the value given for the *compression*
363385
parameter to the constructor for the new entry, or in the *zinfo_or_arcname*
@@ -373,6 +395,12 @@ ZipFile Objects
373395
.. versionchanged:: 3.2
374396
The *compress_type* argument.
375397

398+
.. versionchanged:: 3.6
399+
Calling :meth:`writestr` on a ZipFile created with mode ``'r'`` or
400+
a closed ZipFile will raise a :exc:`ValueError`. Previously,
401+
a :exc:`RuntimeError` was raised.
402+
403+
376404
The following data attributes are also available:
377405

378406

Lib/test/test_zipfile.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -449,15 +449,15 @@ def test_write_default_name(self):
449449

450450
def test_write_to_readonly(self):
451451
"""Check that trying to call write() on a readonly ZipFile object
452-
raises a RuntimeError."""
452+
raises a ValueError."""
453453
with zipfile.ZipFile(TESTFN2, mode="w") as zipfp:
454454
zipfp.writestr("somefile.txt", "bogus")
455455

456456
with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
457-
self.assertRaises(RuntimeError, zipfp.write, TESTFN)
457+
self.assertRaises(ValueError, zipfp.write, TESTFN)
458458

459459
with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
460-
with self.assertRaises(RuntimeError):
460+
with self.assertRaises(ValueError):
461461
zipfp.open(TESTFN, mode='w')
462462

463463
def test_add_file_before_1980(self):
@@ -1210,27 +1210,27 @@ def test_empty_file_raises_BadZipFile(self):
12101210
fp.write("short file")
12111211
self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN)
12121212

1213-
def test_closed_zip_raises_RuntimeError(self):
1213+
def test_closed_zip_raises_ValueError(self):
12141214
"""Verify that testzip() doesn't swallow inappropriate exceptions."""
12151215
data = io.BytesIO()
12161216
with zipfile.ZipFile(data, mode="w") as zipf:
12171217
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
12181218

12191219
# This is correct; calling .read on a closed ZipFile should raise
1220-
# a RuntimeError, and so should calling .testzip. An earlier
1220+
# a ValueError, and so should calling .testzip. An earlier
12211221
# version of .testzip would swallow this exception (and any other)
12221222
# and report that the first file in the archive was corrupt.
1223-
self.assertRaises(RuntimeError, zipf.read, "foo.txt")
1224-
self.assertRaises(RuntimeError, zipf.open, "foo.txt")
1225-
self.assertRaises(RuntimeError, zipf.testzip)
1226-
self.assertRaises(RuntimeError, zipf.writestr, "bogus.txt", "bogus")
1223+
self.assertRaises(ValueError, zipf.read, "foo.txt")
1224+
self.assertRaises(ValueError, zipf.open, "foo.txt")
1225+
self.assertRaises(ValueError, zipf.testzip)
1226+
self.assertRaises(ValueError, zipf.writestr, "bogus.txt", "bogus")
12271227
with open(TESTFN, 'w') as f:
12281228
f.write('zipfile test data')
1229-
self.assertRaises(RuntimeError, zipf.write, TESTFN)
1229+
self.assertRaises(ValueError, zipf.write, TESTFN)
12301230

12311231
def test_bad_constructor_mode(self):
12321232
"""Check that bad modes passed to ZipFile constructor are caught."""
1233-
self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q")
1233+
self.assertRaises(ValueError, zipfile.ZipFile, TESTFN, "q")
12341234

12351235
def test_bad_open_mode(self):
12361236
"""Check that bad modes passed to ZipFile.open are caught."""
@@ -1240,10 +1240,10 @@ def test_bad_open_mode(self):
12401240
with zipfile.ZipFile(TESTFN, mode="r") as zipf:
12411241
# read the data to make sure the file is there
12421242
zipf.read("foo.txt")
1243-
self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q")
1243+
self.assertRaises(ValueError, zipf.open, "foo.txt", "q")
12441244
# universal newlines support is removed
1245-
self.assertRaises(RuntimeError, zipf.open, "foo.txt", "U")
1246-
self.assertRaises(RuntimeError, zipf.open, "foo.txt", "rU")
1245+
self.assertRaises(ValueError, zipf.open, "foo.txt", "U")
1246+
self.assertRaises(ValueError, zipf.open, "foo.txt", "rU")
12471247

12481248
def test_read0(self):
12491249
"""Check that calling read(0) on a ZipExtFile object returns an empty
@@ -1266,7 +1266,7 @@ def test_open_non_existent_item(self):
12661266
def test_bad_compression_mode(self):
12671267
"""Check that bad compression methods passed to ZipFile.open are
12681268
caught."""
1269-
self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1)
1269+
self.assertRaises(NotImplementedError, zipfile.ZipFile, TESTFN, "w", -1)
12701270

12711271
def test_unsupported_compression(self):
12721272
# data is declared as shrunk, but actually deflated
@@ -1423,15 +1423,15 @@ def test_open_conflicting_handles(self):
14231423
with zipf.open('foo', mode='w') as w2:
14241424
w2.write(msg1)
14251425
with zipf.open('bar', mode='w') as w1:
1426-
with self.assertRaises(RuntimeError):
1426+
with self.assertRaises(ValueError):
14271427
zipf.open('handle', mode='w')
1428-
with self.assertRaises(RuntimeError):
1428+
with self.assertRaises(ValueError):
14291429
zipf.open('foo', mode='r')
1430-
with self.assertRaises(RuntimeError):
1430+
with self.assertRaises(ValueError):
14311431
zipf.writestr('str', 'abcde')
1432-
with self.assertRaises(RuntimeError):
1432+
with self.assertRaises(ValueError):
14331433
zipf.write(__file__, 'file')
1434-
with self.assertRaises(RuntimeError):
1434+
with self.assertRaises(ValueError):
14351435
zipf.close()
14361436
w1.write(msg2)
14371437
with zipf.open('baz', mode='w') as w2:

0 commit comments

Comments
 (0)