Search code examples
pythonunzipshutil

shutil.unpack_archive and ziplib both return FileNotFoundError: [Errno 2] No such file or directory


I'm trying to unzip some zip files in Python:


print(f"Unzipping:\n{os.getcwd()}\\{constants.DOWNLOADS_FOLDER}\\{case_number}\\{username_hostname}.zip")

# with zipfile.ZipFile(f"{os.getcwd()}\\{constants.DOWNLOADS_FOLDER}\\{case_number}\\{username_hostname}.zip") as z:

#     z.extractall(path=f"{os.getcwd()}\\{constants.DOWNLOADS_FOLDER}\\{case_number}\\{username_hostname}")

shutil.unpack_archive(f"{os.getcwd()}\\{constants.DOWNLOADS_FOLDER}\\{case_number}\\{username_hostname}.zip",

                      f"{os.getcwd()}\\{constants.DOWNLOADS_FOLDER}\\{case_number}\\{username_hostname}")

print(f"Unzipped:\n{os.getcwd()}\\{constants.DOWNLOADS_FOLDER}\\{case_number}\\{username_hostname}")

It works for most of the zip files (case_number being the same, and username_hostname being different), but I got only 2~3 files which always return:

FileNotFoundError: [Errno 2] No such file or directory: 'D:\\current_workdirectory\\downloads\\case_number\\username_hostname\\path\\OmniDesk \\OmniDesk.pdf'

... or ...

'D:\\current_workdirectory\\downloads\\case_number\\username_hostname\\path\\Users\\username\\Desktop\\path\\OCT 11 to 16th \\2022-10-11.xlsx'

I tried to manually unzip the file (in Windows) and it works fine.

I do notice a strange space at the end of these files' parent foldername, and when I manually unzip the archive, the space is NOT in the foldername of the unpacked archive.

Is this what caused the problem?


case_number and username_hostname is created from sys.argv:

case_number = sys.argv[1]  # e.g., XXX-YYY
username_hostname = sys.argv[2]   # e.g., johnsmith_PC12345

printout:

DEBUG: This is case_number -->F23-003<--
Unzipping:
D:\path\F23-003\username_hostname.zip
...
FileNotFoundError: [Errno 2] No such file or directory:
...

I saw a discussion on cpython' github repo: https://github.com/python/cpython/issues/94018#issuecomment-1160309581

But, according to the repo, this issue should has been solved: gvanrossum pushed a commit to gvanrossum/cpython that referenced this issue on Jul 1, 2022

I'm using Python 3.11.1


Solution

  • I confirmed that Python 3.11.1 hasn't included this commit (mentioned in the question) yet, so I edited Python's built-in zipfile myself:

    (line 1689, original)

    arcname = (x.rstrip('.') for x in arcname.split(pathsep))
    

    to...

    (line 1689)

    arcname = (x.rstrip(' .') for x in arcname.split(pathsep))
    

    ... which solved the problem.

    So, if anyone encounters the same problem, please copy Python's built-in zipfile.py, edit it as described above, and put it into your project folder.

    By importing the edited zipfile.py, you can overwrite Python's built-in troublesome zipfile.py.