Skip to content

Zipimport fails to consume contents() of an imported zip file containing just .pyc files  #96785

Closed

Description

@Horofic

Zipimport fails to consume contents() of an imported zip file containing just .pyc files

Bug report

This code:

from zipimport import zipimporter

def main():
    importer = zipimporter("module.zip")  # zip file containing only __init__.pyc and oops.pyc
    reader = importer.get_resource_reader("oops.oops")  # <zipimport._ZipImportResourceReader>

    modules = reader.contents() # generator containing the names of the imported pyc files
    for module in modules:
        # some other logic to do with the module
        print(module)  # raises the AssertionError when consumed

if __name__ == "__main__":
    main()

Raises an AssertionError exception, when the generator of the contents from zipped modules containing just .pyc files is consumed.

The exception is raised here in the _ZipImportResourceReader class on line #775 in zipimport.py due to an assert on __init__.py, forgetting that .pyc or .pyo files can also be a valid candidates to import.

Snippet in question:

775: assert relative_path.name == '__init__.py'
776: package_path = relative_path.parent
778: subdirs_seen = set()

This is the exact traceback raised using python 3.9:

$ python zimport.py
Traceback (most recent call last):
File "/Users/user/zimport.py", line 15, in <module>
    main()
File "/Users/user/zimport.py", line 10, in main
    for module in modules:
File "<frozen zipimport>", line 775, in contents
AssertionError

Changing the assert statement on line #775 to the following resolves the issue.

775: assert relative_path.name in ('__init__.py', '__init__.pyc', '__init__.pyo')

Your environment

Tested this on on the following Python docker images:

  • python:3.10 (fixed here)
  • python:3.9
  • python:3.8
  • python:3.7

And used the following zip file to reproduce the issue at hand:

Path = module.zip
Type = zip
Physical Size = 781

Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2022-09-07 13:59:23 D....            0            0  oops
2022-09-07 13:58:26 .....          102           92  oops/__init__.pyc
2022-09-07 13:58:21 .....          478          261  oops/oops.pyc
------------------- ----- ------------ ------------  ------------------------
2022-09-07 13:59:23                580          353  2 files, 1 folders

I also tested the same code on the Python 3.8 and 3.7 Docker images. Though, the issue seems to be different and depending on the version used. I did not have time to pin-point the exact issue (yet). But have included the tracebacks for good measure.

Traceback using 3.7:

$ python zimport.py
Traceback (most recent call last):
File "zimport.py", line 19, in <module>
    main()
File "zimport.py", line 10, in main
    reader = importer.get_resource_reader("oops.oops")
File "/usr/local/lib/python3.7/importlib/resources.py", line 312, in contents
    fullname_path = Path(self.zipimporter.get_filename(self.fullname))
zipimport.ZipImportError: can't find module 'oops.oops'

Traceback using 3.8:

$ python zimport.py
Traceback (most recent call last):
File "zimport.py", line 19, in <module>
    main()
File "zimport.py", line 10, in main
    reader = importer.get_resource_reader("oops.oops")
File "<frozen zipimport>", line 771, in contents
File "<frozen zipimport>", line 191, in get_filename
File "<frozen zipimport>", line 721, in _get_module_code
zipimport.ZipImportError: can't find module 'oops.oops'

Activity

  1. gpshead commented on Sep 13, 2022

    @gpshead
    Member

    Yes this was fixed for 3.10+ and later via the #20576 refactoring. Python 3.9 and earlier are in security fixes only mode. https://peps.python.org/pep-0596/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.7 (EOL)end of life3.8 (EOL)end of life3.9 (EOL)end of lifetype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions