Skip to main content

multiarchive

A high level abstraction of multiple archive formats

Installation

uv add multiarchive

Optional dependency for RAR support:

uv add rarfile

ZStandard support requires the backports-zstd package on Python <3.14:

uv add "backports-zstd; python_version < '3.14'"

Quick Start

from multiarchive import Archive

# Open and inspect
with Archive("archive.zip") as arc:
    print(arc.namelist())  # list of member names
    print(len(arc))        # number of members
    print(arc.size)        # total uncompressed size in bytes

# Extract a single file
with Archive("archive.tar.gz") as arc:
    arc.extract("docs/readme.md", path="./output")

# Read file contents without extracting
with Archive("archive.zip") as arc:
    f = arc.open("config.json")
    content = f.read()
    f.close()

# Iterate over members
with Archive("archive.zip") as arc:
    for name in arc:
        if arc.is_file(name):
            print(f"  {name}")

Supported Formats

Format Read Write Extensions
ZIP Yes Yes .zip
TAR Yes Yes .tar
TAR.GZ Yes Yes .tgz, .tar.gz
TAR.BZ2 Yes Yes .tbz, .tbz2, .tar.bz2
TAR.XZ Yes Yes .tar.xz, .tar.lzma
TAR.ZST Yes Yes .tzst, .tar.zst
RAR Yes No .rar

RAR support requires the rarfile package and an external unrar tool.

Reading Archives

Opening

Use the context manager (recommended):

with Archive("file.zip") as arc:
    ...

Or the classmethod:

arc = Archive.open_archive("file.zip")
try:
    arc.namelist()
finally:
    arc.close()

Reading is supported on all formats, but password-protected archives are not supported and will raise a ValueError. If algo isnt explicitly provided, it will attempt to open it as ZIP first, then TAR, then RAR (if rarfile is installed). If all fails, it raises a ValueError.

Listing Members

with Archive("file.zip") as arc:
    names = arc.namelist()  # Just names
    names = arc.members     # alias to namelist

    # extra info (ArchiveMemberInfo objects)
    for info in arc.infolist():
        print(f"{info.name}: {info.uncompressed_size} bytes, mtime={info.mtime}")

Checking Membership

with Archive("file.zip") as arc:
    if "config.json" in arc:
        print("Found!")

    for name in arc:
        if arc.is_file(name):
            ...
        if arc.is_dir(name):
            ...

Extracting

with Archive("file.tar.gz") as arc:
    # Single file
    arc.extract("src/main.py", path="./extracted")

Reading Member Contents

with Archive("file.zip") as arc:
    f = arc.open("data.json")
    if f is not None:
        content = f.read()
        f.close()

Writing Archives

Creating a New Archive

from multiarchive import Archive

# ZIP
with Archive("output.zip", mode="w") as arc:
    ...

# TAR.GZ with compression level
with Archive("output.tar.gz", mode="w", compression_level=9) as arc:
    ...

The format is determined by file extension. Use the algo parameter to override:

with Archive("my_archive", mode="w", algo="tar.xz") as arc:
    ...

Compression Levels

Format Range Default
ZIP 0–9 6
TAR.GZ 0–9 6
TAR.BZ2 1–9 9
TAR.XZ 0–9 6
TAR.ZST 1–22 3

File Information Object

The infolist() method returns ArchiveMemberInfo objects with a unified interface across all formats:

Field Type Description
name str Member filename
uncompressed_size int Original file size in bytes
compressed_size int | None Compressed size (None for TAR)
mtime float Modification time as epoch seconds
mode int | None Unix permission bits
is_dir bool Whether the member is a directory
raw ZipInfo | TarInfo | RarInfo Original backend object (escape hatch)

Factory methods for direct conversion (you shouldn't need these in normal usage):

info = ArchiveMemberInfo.from_zipinfo(zip_info)
info = ArchiveMemberInfo.from_tarinfo(tar_info)
info = ArchiveMemberInfo.from_rarinfo(rar_info)

Properties

Method/Property Description
members Alias for namelist()
size Total uncompressed size of all members
comment / comment= Get/set archive comment (ZIP only, raises ValueError otherwise)

Error Handling

from multiarchive import Archive, BadArchiveError

try:
    with Archive("corrupted.zip") as arc:
        arc.namelist()
except BadArchiveError as e:
    print(f"Archive error: {e}")
except NotImplementedError as e:
    # password-protected (not supported)
    print(f"Not implemented: {e}")
except ValueError as e:
    # Unknown format
    print(f"Value error: {e}")
except FileNotFoundError:
    print("File not found")

API Reference

Archive

Archive(
    filename: str | Path,
    mode: str = "r",
    compression_level: int | None = None,
)
Parameter Description
filename Path to the archive file
mode 'r' for read, 'w' for write, 'a' for append
compression_level Compression level (format-dependent)

Methods

Method Description
open_archive(cls, filename, mode, compression_level) Factory method, returns opened archive
namelist() List of member names
infolist() List of ArchiveMemberInfo objects
extract(member, path) Extract single member
open(member, mode) Open member as file-like object
is_dir(member) Check if member is a directory
is_file(member) Check if member is a file
close() Explicitly close the archive

BadArchiveError

Raised when an archive file is corrupt or in an unsupported format.

ArchiveExtensions

Frozen dataclass mapping format names to their common file extensions:

ArchiveExtensions.zip     # (".zip",)
ArchiveExtensions.gz      # (".tgz", ".tar.gz")
ArchiveExtensions.xz      # (".tar.xz", ".tar.lzma")
# ... etc

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

multiarchive-0.1.2.tar.gz (8.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

multiarchive-0.1.2-py3-none-any.whl (8.9 kB view details)

Uploaded Python 3

File details

Details for the file multiarchive-0.1.2.tar.gz.

File metadata

  • Download URL: multiarchive-0.1.2.tar.gz
  • Upload date:
  • Size: 8.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for multiarchive-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f923c5c9d6cf6e01ec65416cdbbe617a66a7d4f9feaa0e07413d768d147e3e7f
MD5 d657603fb0095c6bd5bc405cefdcdcb3
BLAKE2b-256 02330cb82a9ef8ae7d6eb09ae734f82c5f38a594e2e85c01e14641e589e085b7

See more details on using hashes here.

File details

Details for the file multiarchive-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: multiarchive-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 8.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for multiarchive-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3904217dd3fd2f42277a41f6949712615c789090c4750af03b937d60a8a9d37b
MD5 dc277a5d2e33a64f3a209d853eb909a7
BLAKE2b-256 afaa1c2628b2073e9a159ec69f31e93e17c7c4f51d0b2ce2b044afeb09921c0d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page