-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for os.PathLike filename in zipfile.ZipFile.write() #84686
Comments
|
ZipFile seems to support Pathlike objects pretty well, except in ZipFile.writestr. >>> 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? |
|
Here's a small patch to do this. Everything seems to work fine. On Tue, May 5, 2020 at 4:12 AM Domenico Ragusa <report@bugs.python.org> wrote:
>
>
> New submission from Domenico Ragusa <domenicoragusa@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?
>
>
|
|
I have encountered the same issue with a different zipfile function: The zipfile.ZipFile.getinfo function throws a KeyError when using a pathlib.Path object containing the valid path to an existing zip-file member. I am actually using the zipfile.ZipFile.extract function in my case. This function calls the getinfo function, that in turn throws a key error: traceback.print_exc()
Traceback (most recent call last):
File "<my script file>", line 501, in extractTestFilesZipFolderItem
return Path(zf.extract(zipFileItemPath, path = destinationFolderPath))
File "C:\Progs\Python\Python310\lib\zipfile.py", line 1630, in extract
return self._extract_member(member, path, pwd)
File "C:\Progs\Python\Python310\lib\zipfile.py", line 1669, in _extract_member
member = self.getinfo(member)
File "C:\Progs\Python\Python310\lib\zipfile.py", line 1443, in getinfo
raise KeyError(
KeyError: "There is no item named WindowsPath('<Zip file member path>') in the archive"The code of the function is: from typing import Union
import os
from pathlib import Path
import zipfile
import bdb
from breakOnException import setBreakOnException, getBreakOnException
def extractTestFilesZipFolderItem(zipFilePath : Union[str, os.PathLike], zipFileItemPath : Union[str, os.PathLike], destinationFolderPath : Union[None, str, os.PathLike] = None) -> Path:
# Parameter zipFilePath
if not (isinstance(zipFilePath, str) or isinstance(zipFilePath, os.PathLike)):
raise TypeError('Parameter zipFilePath must be a string or another path-like instance')
# Parameter zipFileItemPath
if not (isinstance(zipFileItemPath, str) or isinstance(zipFileItemPath, os.PathLike)):
raise TypeError('Parameter zipFileItemPath must be a string or another path-like instance')
# Parameter destinationFolderPath
if not (destinationFolderPath is None or isinstance(destinationFolderPath, str) or isinstance(destinationFolderPath, os.PathLike)):
raise TypeError('Parameter destinationFolderPath must be None, a string or another path-like instance')
# Normal code
try:
with zipfile.ZipFile(zipFilePath) as zf:
return Path(zf.extract(zipFileItemPath, path = destinationFolderPath))
except Exception as ex:
if type(ex) not in [KeyboardInterrupt, bdb.BdbQuit] and getBreakOnException():
breakpoint()
raiseThe getBreakOnException function is just a function from a self-made library breakOnException that globally tracks whether I want a breakpoint to be triggered when an exception occurs to be able to investigate the values of the variables that may have caused the exception. When I put 'str(' and ')' around zipFileItemPath like In my opinion, the zipfile functions expecting paths (including file names) should be able to accept any string and path-like object.
|
|
It was discussed previously (maybe several times), and I opposed it. Path objects should only be supported for external paths (see #72418). Internal ZIP file paths do not represent real files, they are simply string keys. Using a Path object to access an entry in the ZIP file is a programming error, and we should not make easier to do such errors. |
|
Thanks, in general I think I agree. Though the
Otherwise as far as supporting it in all situations, what I'm finding as I explore in my draft PR is that it gets a bit messy to support them in "lookup/update" scenarios. I had to use more conditional The original simple PR (#20002) put up by @domragusa even used |
os.PathLike filename= in zipfile.ZipFile.write
os.PathLike filename= in zipfile.ZipFile.writeos.PathLike filename= in zipfile.ZipFile.write()
os.PathLike filename= in zipfile.ZipFile.write()
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
os.PathLikeobjects as filename for ZipFile open, read, write & writestr & ZipInfo #113386The text was updated successfully, but these errors were encountered: