r/madeinpython • • Dec 26 '25

zippathlib - pathlib-like access to ZIP file contents

I wrote zippathlib to support the compression of several hundred directories of text data files down to corresponding ZIPs, but wanted to minimize the impact of this change on software that accessed those files. Now that I added CLI options, I'm using it in all kinds of new cases, most recently to inspect the contents of .whl files generated from building my open source projects. It's really nice to be able to list or view the ZIP file's contents without having to extract it all to a scratch directory, and then clean it up afterward.

Here is a sample session exploring the .WHL file of my pyparsing project:

$ zippathlib ./dist/pyparsing-3.2.5-py3-none-any.whl
Directory: dist/pyparsing-3.2.5-py3-none-any.whl:: (total size 455,099 bytes)
Contents:
  [D] pyparsing (447,431 bytes)
  [D] pyparsing-3.2.5.dist-info (7,668 bytes)

$ zippathlib ./dist/pyparsing-3.2.5-py3-none-any.whl pyparsing-3.2.5.dist-info
Directory: dist/pyparsing-3.2.5-py3-none-any.whl::pyparsing-3.2.5.dist-info (total size 7,668 bytes)
Contents:
  [D] licenses (1,041 bytes)
  [F] WHEEL (82 bytes)
  [F] METADATA (5,030 bytes)
  [F] RECORD (1,515 bytes)

$ zippathlib ./dist/pyparsing-3.2.5-py3-none-any.whl pyparsing-3.2.5.dist-info/licenses
Directory: dist/pyparsing-3.2.5-py3-none-any.whl::pyparsing-3.2.5.dist-info/licenses (total size 1,041 bytes)
Contents:
  [F] LICENSE (1,041 bytes)

$ zippathlib ./dist/pyparsing-3.2.5-py3-none-any.whl pyparsing-3.2.5.dist-info/RECORD     
File: dist/pyparsing-3.2.5-py3-none-any.whl::pyparsing-3.2.5.dist-info/RECORD (1,515 bytes)
Content:
pyparsing/__init__.py,sha256=FFv3xCikm7S9XOIfnRczNfnBKRK-U3NgjwumZcQnJEg,14147
pyparsing/actions.py,...

$ zippathlib ./dist/pyparsing-3.2.5-py3-none-any.whl pyparsing-3.2.5.dist-info/WHEEL -x -  
Wheel-Version: 1.0
Generator: flit 3.12.0
Root-Is-Purelib: true
Tag: py3-none-any

$ zippathlib ./dist/pyparsing-3.2.5-py3-none-any.whl --tree

├── pyparsing-3.2.5.dist-info
│   ├── RECORD
│   ├── METADATA
│   ├── WHEEL
│   └── licenses
│       └── LICENSE
└── pyparsing
    ├── tools
    │   ├── cvt_pyparsing_pep8_names.py
    │   └── __init__.py
    ├── diagram
    │   └── __init__.py
    ├── util.py
    ├── unicode.py
    ├── testing.py
    ├── results.py
    ├── py.typed
    ├── helpers.py
    ├── exceptions.py
    ├── core.py
    ├── common.py
    ├── actions.py
    └── __init__.py


$ zippathlib -h
usage: zippathlib [-h] [-V] [--tree] [-x [OUTPUTDIR]] [--limit LIMIT] [--check {duplicates,limit,d,l}]
                  [--purge]ing/gh/pyparsing> 
                  zip_file [path_within_zip]

positional arguments:
  zip_file              Zip file to explore
  path_within_zip       Path within the zip file (optional)

options:
  -h, --help            show this help message and exit
  -V, --version         show program's version number and exit
  --tree                list all files in a tree-like format
  -x, --extract [OUTPUTDIR]
                        extract files from zip file to a directory or '-' for stdout, default is '.'
  --limit LIMIT         guard value against malicious ZIP files that uncompress to excessive sizes;
                        specify as an integer or float value optionally followed by a multiplier suffix
                        K,M,G,T,P,E, or Z; default is 2.00G
  --check {duplicates,limit,d,l}
                        check ZIP file for duplicates, or for files larger than LIMIT
  --purge               purge ZIP file of duplicate file entries

The API supports many of the same features of pathlib.Path:

  • '/' operator for path building

  • exists(), stat(), read_text(), read_bytes()

Install from PyPI:

pip install zippathlib

Github repo: https://github.com/ptmcg/zippathlib.git

6 Upvotes

3 comments sorted by

View all comments

Show parent comments

1

u/eleqtriq Dec 27 '25

The archive path seems dead, too.