[issue40506] add support for os.Pathlike filenames in zipfile.ZipFile.writestr

Domenico Ragusa report at bugs.python.org
Wed May 6 14:31:13 EDT 2020


Domenico Ragusa <domenicoragusa at gmail.com> added the comment:

Here's a small patch to do this. Everything seems to work fine.
I don't know if where I placed the test (in OtherTests) is the most appropriate.

On Tue, May 5, 2020 at 4:12 AM Domenico Ragusa <report at bugs.python.org> wrote:
>
>
> New submission from Domenico Ragusa <domenicoragusa at gmail.com>:
>
> ZipFile seems to support Pathlike objects pretty well, except in ZipFile.writestr.
> For example:
>
> >>> a = ZipFile(Path('test.zip'), 'w') # this works ok
> >>> a.write(Path('./foo.jpeg'), arcname=PurePath('/some/thing.jpeg')) # this works as well
> >>> a.writestr(PurePath('/test.txt'), 'idk') # this doesn't
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "/usr/lib/python3.8/zipfile.py", line 1788, in writestr
>     zinfo = ZipInfo(filename=zinfo_or_arcname,
>   File "/usr/lib/python3.8/zipfile.py", line 349, in __init__
>     null_byte = filename.find(chr(0))
> AttributeError: 'PurePosixPath' object has no attribute 'find'
>
> I think it would be more consistent if it accepted any kind of paths, it would suffice to call os.fspath in ZipInfo.__init__ when the filename is a Pathlike-object, it's just 2 lines (+ tests, of course).
>
> Can I go ahead and prepare a patch for this?
>
> ----------
> components: Library (Lib)
> messages: 368098
> nosy: d.ragusa
> priority: normal
> severity: normal
> status: open
> title: add support for os.Pathlike filenames in zipfile.ZipFile.writestr
> type: enhancement
> versions: Python 3.9
>
> _______________________________________
> Python tracker <report at bugs.python.org>
> <https://bugs.python.org/issue40506>
> _______________________________________

----------
keywords: +patch
Added file: https://bugs.python.org/file49132/pathlike_writestr.patch

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue40506>
_______________________________________
-------------- next part --------------
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index 29d98c8092..31c83987ab 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -1546,6 +1546,12 @@ class OtherTests(unittest.TestCase):
                 zinfo.flag_bits |= 0x08  # Include an extended local header.
                 orig_zip.writestr(zinfo, data)
 
+    def test_writestr_pathlike_issue40506(self):
+        with zipfile.ZipFile(TESTFN2, 'w') as orig_zip:
+            path = '/foo/bar.txt'
+            orig_zip.writestr(pathlib.PurePath(path), '1234')
+            self.assertEqual(orig_zip.open(path).read(4), b'1234')
+
     def test_close(self):
         """Check that the zipfile is closed after the 'with' block."""
         with zipfile.ZipFile(TESTFN2, "w") as zipfp:
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 8903d6a42e..44b3ee8e63 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -341,6 +341,8 @@ class ZipInfo (object):
     )
 
     def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
+        if isinstance(filename, os.PathLike):
+            filename = os.fspath(filename)
         self.orig_filename = filename   # Original file name in archive
 
         # Terminate the file name at the first null byte.  Null bytes in file


More information about the Python-bugs-list mailing list