README.md
July 11, 2026 ยท View on GitHub
kompress lets you transparently read common compressed files and archives through a pathlib.Path-like interface.
It attempts to keep the API as close to pathlib as practical, but only supports read-oriented operations.
The common case for this is:
- You have a compressed file that contains some text
- You have a function (perhaps from another library that you don't control) that accepts a
pathlib.Pathobject and calls.open(),.read_text(), or.read_bytes()on it
Without wrapping the function or adding logic to let it read from compressed files, this lets you do the following:
from pathlib import Path
from kompress import CPath
def char_count(path: Path) -> int:
# here, if a CPath is passed, it decompresses and returns a string
return len(path.read_text())
inp = input("Enter a file to process: ") # file came from user
char_count(CPath(inp))
For formats containing a directory tree, select a member with the usual / operator:
export = CPath("export.tar.xz")
settings = export / "profile" / "settings.json"
print(settings.read_text())
Supported single-file compression formats:
.gz.bz2.xz.zstand.zstd(on Python older than 3.14, installkompress[zstd]).lz4(installkompress[lz4])
Supported archive formats:
.zip.tar.tgzand.tar.gz.tar.bz2.tar.xz.tar.zst(Python 3.14 or newer)
If it doesn't recognize the filetype, it will just call pathlib.Path.open, reading it like a regular file.
Installing
pip install kompress
Motivation and prior art
The design is driven by one constraint: often you can't change the consumer of the path.
Plenty of third-party code accepts a pathlib.Path, isinstance-checks it, and calls .open()/.read_text()/.iterdir() on it.
So kompress paths have to literally pass as pathlib.Path objects (they subclass it, with some __class__ trickery for the zip adapter), rather than merely being "path-like".
That single requirement is what rules out the existing alternatives:
- stdlib
zipfile.Path(and its standalone counterpart zipp) is the closest thing, and is whatkompress.ZipPathbuilds on -- but it isn't an actualpathlib.Path, only covers zip, andtarfilehas no equivalent at all. - fsspec + universal-pathlib is the mainstream general-purpose answer (
UPatheven subclassespathlib.Path). It's a considerably heavier dependency though, uses URL-style paths (zip://...), and won't transparently decompress a bare.gz/.xzfile on.open(). - PyFilesystem2 (with fs.archive) has its own filesystem abstraction, not compatible with
pathlib.Path; it also seems unmaintained these days. - smart_open does transparent decompression, but only as an
open()replacement -- there is no path object to pass around. - patool/pyunpack and stdlib
shutil.unpack_archiveextract archives to disk, rather than reading members in place. - FUSE mounts (ratarmount, archivemount) give you real paths and fast random access into large archives, but require a mount step and platform support.
- pathlib-abc (which grew out of the Make pathlib extensible effort) is the future-facing way to implement custom path classes, and might eventually become the proper base for kompress. However its classes deliberately don't inherit from
pathlib.Path, so on their own they wouldn't pass theisinstancechecks that motivate this library in the first place.
Originally discussed in this issue (transferred from HPI), which collected many of the links above.