Type codecs, the OID→codec registry, and the per-column result-decoding plan.
ACodecknows how to encode a Python value to wire bytes and decode wire bytes back,
in both binary and text formats. TheCodecRegistrymaps PostgreSQL type OIDs to
codecs. A live connection owns a database-specific registry so server-assigned OIDs never
cross sessions; registries remainthreading.Lock-guarded for safe publication, expose reads
as aMappingProxyTypesnapshot, and fail loud on a conflicting
re-registration (never last-wins) — the chirpshapesregistry discipline. The process-wide
default supplies immutable built-in facts to module consumers and fresh-registry construction.
The E1 spine shipped only the hottest OIDs (ints, text, bool, floats). The E2 long tail —
numeric, the temporal family, uuid/bytea, json/jsonb, and the parametric
array/composite/range/enum families — lands here, wired intobuild_default_registry()
from each family'sLEAF_CODECStuple and its parametric factories. Per-row decode
parallelism across free-threaded workers (epic E6) is built on the immutable snapshot this
registry hands out.
The other E2 deliverable isbuild_codec_plan(): given a RowDescription
and a registry snapshot, it precomputes one(bytes | None) -> Anydecoder per column — the
rightdecode_binary/decode_text half chosen from each field's format_code, None
passed straight through for SQL NULL, parametric array/range/composite columns resolved against
the snapshot, and a UTF-8 / raw-bytes text fallback for any unregistered OID so an unknown
type never crashes the row path. The plan is a plain tuple of closures, computed once per result
set and reused for every row.
This module stays sans-I/O: bytes in, Python objects out; no socket, no anyio.
data.drivers._pelt._codecs
| Name | Type | Default | Description |
|---|---|---|---|
type
|
|
— | |
qualified_name
|
|
— | |
element_type
|
|
— | |
description
|
|
— | |
source_file
|
|
— | |
line_number
|
|
— | |
is_autodoc
|
|
— | |
autodoc_element
|
|
— | |
_autodoc_template
|
|
— | |
_autodoc_url_path
|
|
— | |
_autodoc_page_type
|
|
— | |
title
|
|
— | |
doc_content_hash
|
|
— |
Symbols on this page
An immutable encode/decode pair for one PostgreSQL type.
decode_* take the raw column bytes; encode_*return the raw column bytes.
prefers_binaryselects the wire…
A lock-guarded OID→Codecmap that hands out immutable snapshots.
The E1 hot-path leaf codecs defined inline in this module (ints, floats, bool, text).
Every non-parametric E2 codec, gathered from each family'sLEAF_CODECStuple.
Array/composite/range/enum families contribute nothinghere — they are parametric (the element/field codec is only…
The full set of non-parametric codecs the default registry pre-loads (E1 + E2 leaves).
A fresh registry pre-loaded with the E1 hot-path codecs plus the E2 leaf families.
Registration keeps the fail-loud conflict discipline: each OID is registered…
BuildDEFAULT_REGISTRYlazily on first access.
DEFAULT_REGISTRYcannot be built eagerly at module import: doing so reads each E2 family's
LEAF_CODECSwhile a family-first…
Array OID → element OID (lazy import to stay clear of the family import cycle).
Range OID → element OID, so the planner can resolve a parametric range column's element.
Element OIDs cross-referenced from the leaf families: int4 23,…
Reject binary bytes for an OID without a proven decoder.
Text-format fallback for an unregistered OID: decode UTF-8.
PostgreSQL's text wire format is the type'stypoutputstring in the server encoding (UTF-8 for any…
Resolve the non-NULL decoder for one column from its OID +format_code.
format_code is 1 for binary and 0 for text (PostgreSQL's Bind…
Choose one explicit result format per described column.
A registered codec opts into binary throughprefers_binary. Known parametric arrays and ranges opt in…
Copy a statement description with the formats selected byBind.
Precompute one(bytes | None) -> Anydecoder per column for a result set.
Each returned decoder maps a raw column value (from a …
Codec
class
An immutable encode/decode pair for one PostgreSQL type.
decode_* take the raw column bytes; encode_*return the raw column bytes.
prefers_binaryselects the wire format the driver requests when it controls the choice.
CodecRegistry
class
A lock-guarded OID→Codecmap that hands out immutable snapshots.
_e1_codecs
function
def _e1_codecs() -> tuple[Codec, ...]
The E1 hot-path leaf codecs defined inline in this module (ints, floats, bool, text).
No parameters.
_e2_leaf_codecs
function
def _e2_leaf_codecs() -> tuple[Codec, ...]
Every non-parametric E2 codec, gathered from each family'sLEAF_CODECStuple.
Array/composite/range/enum families contribute nothing here — they are parametric (the
element/field codec is only known at plan time), so theirLEAF_CODECSare empty and they
are wired viabuild_codec_plan() instead. The sibling imports are deferred to call time
to break the_codecs↔ family import cycle.
No parameters.
_builtin_codecs
function
def _builtin_codecs() -> tuple[Codec, ...]
The full set of non-parametric codecs the default registry pre-loads (E1 + E2 leaves).
No parameters.
build_default_registry
function
def build_default_registry() -> CodecRegistry
A fresh registry pre-loaded with the E1 hot-path codecs plus the E2 leaf families.
Registration keeps the fail-loud conflict discipline: each OID is registered exactly once,
so a duplicate OID across families (a packaging bug) raisesValueErrorat build
time rather than silently last-wins.
No parameters.
__getattr__
function
def __getattr__(name: str) -> Any
BuildDEFAULT_REGISTRYlazily on first access.
DEFAULT_REGISTRYcannot be built eagerly at module import: doing so reads each E2 family's
LEAF_CODECS while a family-first import is still resolving its from ._codecs import Codec— the family is only half-initialized at that point, so the read would crash with a
partial-initAttributeError. Deferring the build to first attribute access keeps the
process-wide default a one-liner for callers while staying cycle-safe under any import order.
The build is double-checked-lock guarded so concurrent first accesses on free-threaded
workers materialize exactly one registry. Treated read-only after creation; connections
register extra codecs on a freshbuild_default_registry() for per-database enums,
arrays, ranges, and composites.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
name
|
str
|
— |
_array_element_oid_map
function
def _array_element_oid_map() -> Mapping[int, int]
Array OID → element OID (lazy import to stay clear of the family import cycle).
No parameters.
_range_element_oid_map
function
def _range_element_oid_map() -> Mapping[int, int]
Range OID → element OID, so the planner can resolve a parametric range column's element.
Element OIDs cross-referenced from the leaf families: int4 23, int8 20, numeric 1700,
timestamp 1114, timestamptz 1184, date 1082 — seepg_type.dat. Lazy-imported to stay
clear of the_codecs↔ family import cycle.
No parameters.
_unsupported_binary_fallback
function
def _unsupported_binary_fallback(data: bytes) -> Any
Reject binary bytes for an OID without a proven decoder.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
data
|
bytes
|
— |
_text_utf8_fallback
function
def _text_utf8_fallback(data: bytes) -> str
Text-format fallback for an unregistered OID: decode UTF-8.
PostgreSQL's text wire format is the type'stypoutputstring in the server encoding
(UTF-8 for any modern deployment), so a faithful str is the safe, non-crashing default.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
data
|
bytes
|
— |
_column_decoder
function
def _column_decoder(field: FieldDescription, snapshot: Mapping[int, Codec]) -> Callable[[bytes], Any]
Resolve the non-NULL decoder for one column from its OID +format_code.
format_code is 1 for binary and 0 for text (PostgreSQL's Bind/RowDescription
convention). A registered OID uses the matching half of itsCodec; a known
array/range OID is resolved parametrically againstsnapshot; an unregistered OID falls
back to raw-bytes (binary) or UTF-8 (text) so the row path never crashes on an unknown type.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
field
|
FieldDescription
|
— | |
snapshot
|
Mapping[int, Codec]
|
— |
result_format_codes
function
def result_format_codes(row_desc: RowDescription, registry_snapshot: Mapping[int, Codec]) -> tuple[int, ...]
Choose one explicit result format per described column.
A registered codec opts into binary throughprefers_binary. Known
parametric arrays and ranges opt in when their element codec is available.
Every unresolved OID stays text, preserving PostgreSQL's lossless output
fallback instead of requesting undecodable bytes.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
row_desc
|
RowDescription
|
— | |
registry_snapshot
|
Mapping[int, Codec]
|
— |
with_result_formats
function
def with_result_formats(row_desc: RowDescription, formats: Sequence[int]) -> RowDescription
Copy a statement description with the formats selected byBind.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
row_desc
|
RowDescription
|
— | |
formats
|
Sequence[int]
|
— |
build_codec_plan
function
def build_codec_plan(row_desc: RowDescription, registry_snapshot: Mapping[int, Codec]) -> tuple[Callable[[bytes | None], Any], ...]
Precompute one(bytes | None) -> Anydecoder per column for a result set.
Each returned decoder maps a raw column value (from aDataRow) to a
Python object:None (SQL NULL) passes straight through as None; otherwise the column
bytes go through the resolved per-column decoder. Computing the plan once per
RowDescription— rather than re-resolving the codec for every cell —
keeps the per-row loop a tuple of bound closures, which is what makes free-threaded row decode
cheap (epic E6).registry_snapshot is an immutable snapshot() view, so
the plan is lock-free.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
row_desc
|
RowDescription
|
— | |
registry_snapshot
|
Mapping[int, Codec]
|
— |
View source · /home/runner/work/chirp/chirp/site/../src/chirp/data/drivers/_pelt/_codecs.py:1