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
python -mzipfile fails to unzip files with folders created by zip #66397
Comments
With Python 3.4.1: $ mkdir foo; zip -r foo{,}; python -mzipfile -e foo.zip dest
adding: foo/ (stored 0%)
Traceback (most recent call last):
File "/usr/lib/python3.4/runpy.py", line 170, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.4/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/usr/lib/python3.4/zipfile.py", line 1799, in <module>
main()
File "/usr/lib/python3.4/zipfile.py", line 1777, in main
with open(tgt, 'wb') as fp:
IsADirectoryError: [Errno 21] Is a directory: 'dest/foo/' Note that zipfile is actually able to unzip the file: $ python -c 'from zipfile import *; ZipFile("foo.zip").extractall("dest")' works fine. If the zip file is created by "python -mzipfile -c foo.zip foo" then there is no problem. Likewise, if there are no folders in the zip file (but just a collection of files) then there is no problem. |
The reason behind this was that zipfile.py currently handles empty directories in zipfiles incorrectly. On lines 1774 - 1778 in Lib/zipfile.py: tgtdir = os.path.dirname(tgt)
if not os.path.exists(tgtdir):
os.makedirs(tgtdir)
with open(tgt, 'wb') as fp:
fp.write(zf.read(path)) In the case described above, tgt is 'dest/foo/' because the directory is empty. For non-empty directories, tgt would be a file in the directory i.e. 'dest/foo/a'. In the empty directory case, the directory will be created, but then opened as file (which will throw the error shown above). When compressing the file with 'python -mzipfile -c', zipfile.py would not add empty directories to the zipfile. Hence, the zip file generated is empty. This patch fixes both issues. In the decompression case, I utilize the Zipfile.extractall() function instead of extracting each file manually. The extractall() function handles empty directories correctly. For the compression case, I added a check to add an empty directory to the zip file. |
New changeset ffa5bfe75c3a by Serhiy Storchaka in branch '2.7': New changeset 7b933005c492 by Serhiy Storchaka in branch '3.4': New changeset dc77ad3a17aa by Serhiy Storchaka in branch 'default': |
Applied first part of the patch. Thank you Ryan. For the rest please open separate issue. |
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:
The text was updated successfully, but these errors were encountered: