diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 8e437e5cb2b..f9ee740eb6f 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1655,6 +1655,33 @@ class OtherTests(unittest.TestCase): self.assertRaises(ValueError, zipfile.ZipInfo, 'seventies', (1979, 1, 1, 0, 0, 0)) + def test_create_empty_zipinfo_repr(self): + """Before bpo-26185, repr() on empty ZipInfo object was failing.""" + zi = zipfile.ZipInfo(filename="empty") + self.assertEqual(repr(zi), "") + + def test_create_empty_zipinfo_default_attributes(self): + """Ensure all required attributes are set.""" + zi = zipfile.ZipInfo() + self.assertEqual(zi.orig_filename, "NoName") + self.assertEqual(zi.filename, "NoName") + self.assertEqual(zi.date_time, (1980, 1, 1, 0, 0, 0)) + self.assertEqual(zi.compress_type, zipfile.ZIP_STORED) + self.assertEqual(zi.comment, b"") + self.assertEqual(zi.extra, b"") + self.assertIn(zi.create_system, (0, 3)) + self.assertEqual(zi.create_version, zipfile.DEFAULT_VERSION) + self.assertEqual(zi.extract_version, zipfile.DEFAULT_VERSION) + self.assertEqual(zi.reserved, 0) + self.assertEqual(zi.flag_bits, 0) + self.assertEqual(zi.volume, 0) + self.assertEqual(zi.internal_attr, 0) + self.assertEqual(zi.external_attr, 0) + + # Before bpo-26185, both were missing + self.assertEqual(zi.file_size, 0) + self.assertEqual(zi.compress_size, 0) + def test_zipfile_with_short_extra_field(self): """If an extra field in the header is less than 4 bytes, skip it.""" zipdata = ( diff --git a/Lib/zipfile.py b/Lib/zipfile.py index dfd09079501..c2c5b6a2a44 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -376,11 +376,11 @@ class ZipInfo (object): self.volume = 0 # Volume number of file header self.internal_attr = 0 # Internal attributes self.external_attr = 0 # External file attributes + self.compress_size = 0 # Size of the compressed file + self.file_size = 0 # Size of the uncompressed file # Other attributes are set by class ZipFile: # header_offset Byte offset to the file header # CRC CRC-32 of the uncompressed file - # compress_size Size of the compressed file - # file_size Size of the uncompressed file def __repr__(self): result = ['<%s filename=%r' % (self.__class__.__name__, self.filename)] @@ -1564,9 +1564,7 @@ class ZipFile: "another write handle open on it. " "Close the first handle before opening another.") - # Sizes and CRC are overwritten with correct data after processing the file - if not hasattr(zinfo, 'file_size'): - zinfo.file_size = 0 + # Size and CRC are overwritten with correct data after processing the file zinfo.compress_size = 0 zinfo.CRC = 0 diff --git a/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst b/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst new file mode 100644 index 00000000000..dc71dae6924 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst @@ -0,0 +1,2 @@ +Fix :func:`repr` on empty :class:`ZipInfo` object. Patch by Mickaƫl +Schoentgen.