diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index a77e49a76438267..9b8b15e9636f0a6 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -866,6 +866,9 @@ Instances have the following methods and attributes: Size of the uncompressed file. +.. attribute:: ZipInfo.mode + + The mode of the file (permissions) .. _zipfile-commandline: .. program:: zipfile diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index a51764b92973630..3ad3a2f0b378be6 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -2162,6 +2162,21 @@ def test_create_empty_zipinfo_default_attributes(self): self.assertEqual(zi.file_size, 0) self.assertEqual(zi.compress_size, 0) + def test_zipinfo_mode(self): + zinfo = zipfile.ZipInfo() + self.assertEqual(zinfo.mode, 0) + + zinfo.mode = 0o777 + self.assertEqual(zinfo.mode, 0o777) + + zinfo.mode = 0o700 + self.assertEqual(zinfo.mode, 0o700) + + # Setting the file mode should not overwrite the file type + zinfo.mode = 0xFFFF + self.assertLessEqual(zinfo.mode, 0o777) + self.assertEqual(zinfo.external_attr >> 16 >> 9, 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/__init__.py b/Lib/zipfile/__init__.py index fe629ed1cf2fc5c..f0f8ee4638a2f16 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -592,6 +592,14 @@ def from_file(cls, filename, arcname=None, *, strict_timestamps=True): return zinfo + @property + def mode(self): + return (self.external_attr >> 16) & 0o777 + + @mode.setter + def mode(self, value): + self.external_attr = self.external_attr & ~(0o777 << 16) | ((value & 0o777) << 16) + def is_dir(self): """Return True if this archive member is a directory.""" return self.filename.endswith('/') diff --git a/Misc/NEWS.d/next/Library/2022-04-02-14-47-18.bpo-47200.viCa8l.rst b/Misc/NEWS.d/next/Library/2022-04-02-14-47-18.bpo-47200.viCa8l.rst new file mode 100644 index 000000000000000..59183af8f4f4e2b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-02-14-47-18.bpo-47200.viCa8l.rst @@ -0,0 +1 @@ +Adds the :attr:`ZipInfo.mode` attribute to get and set the mode of a file