Skip to content

zipfile.Path.open is slow when opening for writing in a ZIP with many entries #126565

Closed

Description

@janhicken

Bug report

Bug description:

I'm using the zipfile module to create a ZIP file with thousands of members. Each file is created by creating a corresponding zipfile.Path object first and then calling .open() on it.

The implementation of open() contains a check whether the file already exists when opening a file in read mode:

if not self.exists() and zip_mode == 'r':
    raise FileNotFoundError(self)

However, self.exists() is called even in write mode, because it is the and operator's first argument.
The call to self.exists() is quite slow however, because this requires the ZIP file's .namelist() to be computed, which in turn requires to compute all the implied directories. After all, this is the reason why the FastLookup optimization exists for ZIP files in read mode.

I found this issue after profiling my application and was surprised that more than half of its execution time was spent in computing implied ZIP directories.

I would propose to swap the and arguments so the check looks like this:

if zip_mode == "r" and not self.exists():
    raise FileNotFoundError(self)

This will cause the self.exists() check to only be run in read mode, where the check is fast because of FastLookup anyway.

I'm happy to provide a pull request with this change.

CPython versions tested on:

3.11, 3.12

Operating systems tested on:

Linux, macOS

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Nov 8, 2024
  2. picnixz commented on Nov 8, 2024

    @picnixz
    Member

    I'd say such PR would be welcomed and you could also check if other tests need that kind of optimization. Let me confirm with a core dev: cc @jaraco

  3. added 2 commits that reference this issue on Nov 8, 2024
  4. added a commit that references this issue on Nov 10, 2024
  5. added 2 commits that reference this issue on Nov 10, 2024
  6. added
    3.12only security fixes
    3.13only security fixes
    3.14bugs and security fixes
    on Nov 10, 2024
  7. jaraco commented on Nov 10, 2024

    @jaraco
    Member

    This fix is also available on older Pythons with zipp 3.21.0.

  8. added 2 commits that reference this issue on Nov 10, 2024
  9. picnixz commented on Nov 10, 2024

    @picnixz
    Member

    Closing since merged and backported. Thank you all.

  10. gpshead commented on Nov 10, 2024

    @gpshead
    Member

    thanks for finding and fixing this!

  11. added a commit that references this issue on Dec 8, 2024
  12. added a commit that references this issue on Jan 12, 2025
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.12only security fixes3.13only security fixes3.14bugs and security fixesperformancePerformance or resource usagestdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions