Skip to main content

unpackio for Python

unpackio is the Python distribution for the repository's security-focused, unpack-only Rust 7z, ZIP, RPM, CPIO, Debian-package, and ARJ readers and its separate LZ4/Zstandard/Unix .Z stream readers. The package imports as unpackio; its implementation module is unpackio._native.

The binding delegates all parsing, graph validation, decoding, cryptography, CRC verification, limits, and path classification to the stable Rust core. It does not create archives and does not automatically extract archive names to the filesystem.

ZIP and RPM use concrete APIs rather than pretending to be 7z archives:

import io
import unpackio

zip_archive = unpackio.open_zip_path("input.zip", password=b"zip-password")
for entry in zip_archive.entries():
    print(entry.index, entry.name, entry.compression_method, entry.encryption)

rpm = unpackio.open_rpm_path("package.rpm")
print(rpm.payload_compression, rpm.header.value(1000))

output = io.BytesIO()
rpm.extract_entry_to(0, output)

Use open_zip_bytes/open_zip_path and open_rpm_bytes/open_rpm_path. ZIP passwords are bytes and remain scoped to one ZipArchive; RPM accepts no password. Both formats preserve raw names as bytes, duplicate order, metadata, and safe-path classification. Neither API writes a name to disk or returns all decoded payloads as one object.

Format-specific data model

Applications consume the native, format-specific unpackio objects directly:

import io
import unpackio

archive = unpackio.open_zip_path("sample.zip", password=b"infected")
entry = archive.entries()[0]
verified = io.BytesIO()
archive.extract_entry_to(entry.index, verified)

package = unpackio.open_rpm_path("sample.rpm")
print(package.header.as_named_dict().get("name"))
payload = io.BytesIO()
package.extract_entry_to(package.entries()[0].index, payload)

ZipEntry exposes decoded/raw names, comments, extras, sizes, CRC, DOS timestamp, method, flags, creator/extractor versions, attributes, local-header offset, encryption kind, and directory metadata. Passwords are supplied when opening a ZipArchive; trying another password creates another per-archive session. Even a zero-length encrypted member must be extracted so its password verifier and authentication data are checked.

RpmArchive.header and .signature_header retain ordered typed tags. as_named_dict() adds a complete symbolic projection, preserves unknown tags under numeric keys, returns scalar integers for single-value numeric tags, and selects the first locale for I18N values. RPM opening validates the complete supported package, including applicable digests, before member data is exposed.

These APIs contain no writer, extractall, automatic path use, or runtime fallback. Callers must apply their own policy before using a metadata name as a path.

ZipArchive.extract_entries_to and RpmArchive.extract_entries_to use the same three callbacks as the 7z batch protocol, with ZipEntry or RpmEntry passed to begin_entry. One work budget and cancellation token cover the complete call, chunks are bounded, callback exceptions retain their identity, and finish_entry is the integrity-verified boundary. ZIP verifies authentication/size/applicable CRC before finalization; RPM has already verified supported package digests and rechecks applicable CRC-newc member checksums. A caller should still stage output if callback failure must be atomic.

RPM typed headers use numeric tags. RpmHeader.entries() retains order and duplicates; .value(tag) returns the last effective value and .as_dict() is a convenience projection. OpenPGP blobs are exposed but not authenticated. The current RPM object retains the bounded decoded CPIO payload, reported by retained_payload_bytes.

Standalone CPIO, Debian packages, and ARJ likewise use concrete APIs:

import io
import unpackio

cpio = unpackio.open_cpio_path("payload.cpio")
deb = unpackio.open_deb_path("package.deb")
arj = unpackio.open_arj_path("archive.arj")

for entry in cpio.entries():
    print(entry.index, entry.format, entry.raw_name, entry.mode)
for entry in deb.entries():
    print(entry.index, entry.section, entry.raw_name, entry.kind)
for entry in arj.entries():
    print(entry.index, entry.compression_method, entry.raw_name, entry.crc32)

verified = io.BytesIO()
deb.extract_entry_to(0, verified)

Use the corresponding open_cpio_bytes, open_deb_bytes, or open_arj_bytes function for owned byte input. DebArchive.members() lists the outer ar members, while entries() lists the indexed control/data tar entries; extract_member_to exposes an outer member to a caller-selected writer. CPIO symlink targets are returned as raw bytes by symlink_target. All three preserve raw names and safe-path classification without applying paths, modes, ownership, devices, or links.

Their extract_entries_to methods use the same begin/write/finish protocol with CpioEntry, DebEntry, or ArjEntry. A successful finish_entry is the integrity boundary for every checksum the format provides: CRC-newc for CPIO, the already validated tar header for Debian, and member CRC-32 for ARJ. Layouts without a payload checksum do not gain one. Writer/sink exceptions and cancellation retain their original Python identity, and chunks remain bounded. For atomic publication, stage output until the operation succeeds.

The current Debian object retains both bounded decoded tar images. ARJ supports single-volume methods 0--4 and empty no-data methods 8/9; encrypted entries remain listable but extraction raises PasswordRequired, while split volumes and security envelopes are typed unsupported. Standalone CPIO accepts raw newc, CRC-newc, odc, and historical binary inputs but does not automatically unwrap a compression stream.

Decoded output is delivered to a Python writer or bounded callback. A writer or callback can observe bytes before a trailing archive CRC is checked, so the operation's successful return is the integrity boundary. Use a temporary destination when output must be published atomically.

Python retains ownership of any 7z password str or ZIP password bytes passed by the caller and cannot erase that Python object. Every Rust-side password copy is zeroized and kept only in the corresponding archive session.

Standalone inputs never become synthetic archives. Use open_stream_bytes or open_stream_path, inspect .info, and select a writer or callback yourself:

import io
import unpackio

stream = unpackio.open_stream_path("payload.zst")
print(stream.info.format, stream.info.uncompressed_size)

output = io.BytesIO()
decoded_bytes = stream.extract_to(output)

The optional format= value accepts lz4, zstd/zstandard, or z/compress/unix-compress; omit it for magic detection. The binding never removes an input suffix or opens a derived output path. stream(callback) sends bounded chunks and preserves Python exceptions or False cancellation. verify() decodes to a discard sink. There is intentionally no Python method that returns the complete output as one object.

For LZ4 and Zstandard, successful return means every checksum declared by the frames was finalized. A writer/callback may have observed earlier unverified chunks, so atomic publication still requires caller-managed staging. Unix .Z contains no checksum or declared decoded size; successful return means the LZW decoder reached a valid EOF under the configured bounds, not that the bytes are authenticated or protected against clean-boundary truncation.

import unpackio

archive = unpackio.open_path("example.7z")
for entry in archive.entries():
    print(entry.index, entry.name, entry.size, entry.crc32)

with open("caller-selected-output.bin", "wb") as output:
    verified_bytes = archive.extract_entry_to(0, output)

stream_entry(index, callback) sends the same bounded chunks without first forming a complete Python output object. Return None or True to continue, or False to cancel.

extract_entries_to(sink) is the natural-order batch surface for solid archives. It uses one core work budget and cancellation token for the entire operation and decodes each solid folder at most once. The sink is structural; archive names remain metadata and are never opened as filesystem paths:

class Sink:
    def begin_entry(self, entry: unpackio.Entry, size: int) -> None:
        # Select a destination by entry.index and caller policy, not entry.name.
        ...

    def write_entry(self, index: int, chunk: bytes) -> None:
        # Chunks are bounded (currently at most 4 KiB).
        ...

    def finish_entry(self, index: int) -> None:
        # This callback is the CRC-verified success boundary for the entry.
        ...

verified_bytes = archive.extract_entries_to(Sink())

Each sink method returns None or True to continue, or False to cancel. Python exceptions are re-raised unchanged. begin_entry and write_entry may be observed before a later member CRC failure; only finish_entry means that the core verified the applicable member and folder CRCs. A Python exception raised by finish_entry still makes the overall operation fail. Duplicate names remain separate index-addressed entries, and empty files receive begin_entry followed by finish_entry without a write call. Streamless directories and anti-items intentionally produce no sink event; callers that need to materialize those records must use archive.entries() metadata and their own validated policy.

open_volumes accepts a callable or an object with open_volume(index, expected_name) returning bytes or None; all returned parts remain subject to the core volume and aggregate-input limits.

Published releases use six optimized cp39-abi3 wheels covering Linux, macOS, and Windows on x86-64 and ARM64. Each exact wheel must pass this binding suite on Python 3.12, 3.13, and 3.14 before the separately protected manual PyPI publication step is available. The wheel adds no Python runtime dependency or command-line entry point. See the repository RELEASING.md for the release and Trusted Publisher procedure.

For a local development build:

python -m pip install 'maturin==1.13.3'
maturin develop --manifest-path bindings/python/Cargo.toml
python -m unittest discover -s bindings/python/tests -v

See the repository API.md, SECURITY.md, COMPATIBILITY.md, and bindings/python/AGENTS.md for the complete contracts and current support evidence.

Metadata

Release files for unpackio 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for unpackio 0.1.1
File Size Uploaded Provenance Actions
unpackio-0.1.1.tar.gz 341.4 kB With provenance Details for unpackio-0.1.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for unpackio 0.1.1
File Actions
unpackio-0.1.1-cp39-abi3-win_arm64.whl CPython 3.9 abi3 Windows ARM64 Details for unpackio-0.1.1-cp39-abi3-win_arm64.whl
unpackio-0.1.1-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details for unpackio-0.1.1-cp39-abi3-win_amd64.whl
unpackio-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details for unpackio-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
unpackio-0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details for unpackio-0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
unpackio-0.1.1-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details for unpackio-0.1.1-cp39-abi3-macosx_11_0_arm64.whl
unpackio-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details for unpackio-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl

Total release size: 6.1 MB

Release files / unpackio-0.1.1.tar.gz

Download URL unpackio-0.1.1.tar.gz
Size 341.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f33409bfa0c782845d8ae12c33536005e340d64dd24c682528e42f07c8145eac
BLAKE2b-256 checksum
How to use checksums
31c1ae2be4573a1cd725d64dc7f2e38b3e2c9e5808170e2125697c25b162139e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release files / unpackio-0.1.1-cp39-abi3-win_arm64.whl

Download URL unpackio-0.1.1-cp39-abi3-win_arm64.whl
Size 924.7 kB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
d6fe0b956d69b3737b55f809893a934b3ab0266bd81cb911bc394bd2f8e5045c
BLAKE2b-256 checksum
How to use checksums
c6d27042446fbdcb3e1db36274d7e6dad9e2a5ad0b4f9968f6ee0ba75c7fb9a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release files / unpackio-0.1.1-cp39-abi3-win_amd64.whl

Download URL unpackio-0.1.1-cp39-abi3-win_amd64.whl
Size 969.9 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
20b1aa8e0484d6ea6a10d78bd45553b9c888005f20d2d3b109481614425683dd
BLAKE2b-256 checksum
How to use checksums
56b3d3113a45e844d8b25f03eb3cbddb9f51ca5593773371343aa7109dd61586
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release files / unpackio-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL unpackio-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.0 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
22894777632a132c26c88769a02537d029e9edeb5895ee9f677a04f08e0c2255
BLAKE2b-256 checksum
How to use checksums
ff5a7b573ffadaf891367ac330f31fb3c22e2d82ee767a1b4fad8a9d9c99e747
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release files / unpackio-0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL unpackio-0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 985.5 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
0f405d5bb401febfd930f7ac26f3a2a0003248933e1189bbbf32f4a6627a19bd
BLAKE2b-256 checksum
How to use checksums
edc84f3951dd47116521b46b2c0cd72f43cabbe6393439ed6381df544832e7f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release files / unpackio-0.1.1-cp39-abi3-macosx_11_0_arm64.whl

Download URL unpackio-0.1.1-cp39-abi3-macosx_11_0_arm64.whl
Size 921.6 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b82a798cfb917e898976188f166cdea7e2839ca5456a64ca2da3d90b68b05ee9
BLAKE2b-256 checksum
How to use checksums
d53de3d7433bb88f7faa7ea989ad99eb91631c00e0225ef2286219d7cef5408c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release files / unpackio-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl

Download URL unpackio-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl
Size 967.0 kB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
817bc22e39b500b2b23e3e08fa13ea8e596f18103dc8ac2d2d88710124e51b59
BLAKE2b-256 checksum
How to use checksums
9c9d569a9f1c3a81e28f7d9465a8a27bab427d91623bd4fac1e91b89160619e3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Security for unpackio 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 7 files in this release have been uploaded with provenance metadata.

Select from 7 files

Attestation for unpackio-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

7 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page