Skip to content

yggdrasil.enums.codec

codec

Compression codec abstraction.

A :class:Codec encapsulates a compression scheme. Each concrete codec provides:

  • Bytes roundtrip — :meth:compress_bytes, :meth:decompress_bytes for small/medium payloads held entirely in memory.
  • Streaming roundtrip — :meth:compress, :meth:decompress stream chunk-by-chunk between :class:IO buffers when the underlying library exposes a streaming encoder/decoder (gzip, zstd, lz4, bz2, xz, lzma). Snappy and Brotli fall back to a bytes roundtrip since their Python bindings don't expose streaming.
  • Partial decode — :meth:read_start_end reads only the head and tail of the uncompressed stream without materializing the entire decoded payload.

Streaming support is advertised by the :attr:is_streaming flag so callers can decide whether to trust :meth:compress / :meth:decompress with a large input, or fall back to a different strategy for non-streaming codecs.

Implementation note — context managers

All concrete streaming reader/writer adapters are driven through with blocks in :meth:_stream_roundtrip and :meth:read_start_end. This matters specifically for zstandard.ZstdCompressionWriter, which rejects write() calls when not inside an active context manager (raises ZstdError: write() must be called from an active context manager). The with pattern also stops silently swallowing close()-time errors, which are meaningful for formats that write the final frame/footer on close (gzip, zstd, lz4): a swallowed error there produces a truncated output that decompresses cleanly right up to the point where the real data ends.

Codec

Bases: ABC

Abstract compression codec.

is_streaming property

is_streaming: bool

True when both compress and decompress have streaming paths.

Callers with large (GiB-scale) inputs should check this before passing them to :meth:compress / :meth:decompress. When False, those methods fall back to materializing the full payload in memory through :meth:compress_bytes / :meth:decompress_bytes.

compress

compress(src: 'IO') -> 'IO'

Compress src into a new :class:IO.

Streams chunk-by-chunk when :meth:_open_compress_writer is available. Otherwise falls back to a full-in-memory bytes roundtrip — callers with multi-GiB inputs should inspect :attr:is_streaming first.

The source cursor is restored on exit.

decompress

decompress(src: 'IO', copy: bool = True) -> 'IO'

Decompress src into a new :class:IO.

Streams chunk-by-chunk when :meth:_open_decompress_reader is available. Otherwise falls back to a full-in-memory bytes roundtrip — callers with multi-GiB compressed inputs should inspect :attr:is_streaming first.

The source cursor is restored on exit.

read_start_end

read_start_end(
    src: "IO | bytes | bytearray | memoryview",
    *,
    n_start: int = 64,
    n_end: int = 64,
    chunk_size: int = _CHUNK
) -> tuple[bytes, bytes]

Return the first n_start and last n_end bytes of the decoded stream.

Streams the decompression and keeps only a bounded amount of state in memory (:math:n\_end + chunk\_size bytes) — safe for very large compressed inputs when the codec supports streaming decompression.

When the codec does NOT expose a streaming decoder, falls back to a full :meth:decompress_bytes call, which materializes the whole uncompressed payload in memory.

from_ classmethod

from_(obj: Any, default: 'Codec | None' = ...) -> 'Codec | None'

Parse an arbitrary input into a Codec instance.

Accepts: - :class:Codec instances (returned as-is). - Short names like "gzip", "zstd" (case-insensitive). - Anything :meth:MimeType.parse can resolve to a codec mime. - None → returns default.

Codecs

Singleton class for accessing all registered codecs.