Skip to main content

fletchr-uintn

A PyArrow extension type for unsigned integers of arbitrary fixed bit width N ∈ [1, 64]. The bit width lives in the Arrow type rather than as sidecar schema metadata, so mismatched widths fail loudly on concat, the width survives slice / cast / IPC / Parquet round-trips, and any column-level operation that wants to know "how many bits does this hold" reads it off column.type.bits.

Why?

PyArrow's built-in uint8 / uint16 / uint32 / uint64 cover only the four power-of-two widths native to most CPUs. Protocol and binary formats routinely use other widths (10, 12, 14, 24, 48), and the usual workarounds — over-allocating (uint16 for a 12-bit field) or passing the width out-of-band in schema metadata — either lose the constraint on bitwise ops or drop it on the next slice. fletchr.uintn(bits=N) puts the width in the type and ships bit-width-safe kernels that keep padding bits zero across every operation.

Features

  • Storage in the smallest native uint8 / uint16 / uint32 / uint64 container that fits N; padding bits above N are kept zero across construction and every operation.
  • Lossless round-trip through Arrow IPC, Arrow Flight, and Parquet. Readers that don't have the extension registered see the raw uintN storage transparently — no exotic types in the wire format.
  • Full Arrow null support via the standard validity bitmap.
  • Bit-width-safe bitwise operators (~, &, |, ^, shifts) plus a fletchr_uintn.compute module (comparisons, popcount, bit-reversal, parity, exact reductions, ...) — padding bits never leak.
  • Cross-language wire format pinned in SPEC.md so Arrow readers in Java, C++, Go, R, JavaScript, etc. can implement compatible deserializers.

Install

uv add fletchr-uintn        # or: pip install fletchr-uintn

Requires Python 3.9+, NumPy 2.0+, and PyArrow 17+.

Quickstart

import pyarrow as pa
import pyarrow.parquet as pq
from fletchr_uintn import uintn_array

# 12-bit values — fit in a uint16 container, but the type knows it's 12 bits.
a = uintn_array([0, 1, 4095, None, 100], bits=12)
a.type            # UIntNType(bits=12)
a.to_pylist()     # [0, 1, 4095, None, 100]

# Bitwise ops respect the declared width: ~0 is 4095, not 65535.
(~a).to_pylist()  # [4095, 4094, 0, None, 3995]

# Composes as a column inside any pa.Table; round-trips through Parquet.
pq.write_table(pa.table({"x": a}), "out.parquet")
back = pq.read_table("out.parquet").column("x")
assert back.type.bits == 12

# Mismatched bit widths fail at the Arrow type system, not silently:
pa.concat_arrays([a, uintn_array([0, 1], bits=10)])  # raises ArrowInvalid

Public API

from fletchr_uintn import (
    UIntNType,             # the pa.ExtensionType
    UIntNArray,            # the pa.ExtensionArray (data structure + operator sugar)
    compute,               # named kernels: comparisons, bitwise, reductions
    uintn_array,           # validated factory; dispatches on input type
    pack_bits,             # inverse of UIntNArray.unpack_bits
    to_numpy_zero_filled,  # numeric pa.Array -> ndarray, nulls read as 0
)

The extension type registers itself on import, so any pa.Table deserialized after import fletchr_uintn will surface UIntNArray columns instead of raw uintN storage.

fletchr_uintn.compute is to UIntNArray what pyarrow.compute is to pyarrow.Array: the array itself is a data structure (construction, indexing, conversions, whole-array ==, and & | ^ ~ << >> operator sugar), while every named element-wise / reduction operation is a free function that also accepts ChunkedArray columns:

import fletchr_uintn.compute as uc

uc.equal(a, 5)            # pa.BooleanArray mask (pc.equal lacks a kernel)
uc.bit_wise_reverse(a)    # width-aware bit reversal
uc.sum(a)                 # exact at every width — no uint64 wraparound

(arr == 5 raises with guidance rather than silently comparing identity.) For any pyarrow.compute kernel compute doesn't wrap, arr.storage is the escape hatch: it's the raw uintN array, and every value is already masked to the declared width, so pc.<kernel>(arr.storage, ...) is safe — rewrap a result with uintn_array(result, bits=arr.bits) if you need the type back.

Links

License

MIT.

Download files

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

Source Distribution

fletchr_uintn-0.2.0.tar.gz (34.3 kB view details)

Uploaded Source

Built Distribution

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

fletchr_uintn-0.2.0-py3-none-any.whl (23.9 kB view details)

Uploaded Python 3

File details

Details for the file fletchr_uintn-0.2.0.tar.gz.

File metadata

  • Download URL: fletchr_uintn-0.2.0.tar.gz
  • Upload date:
  • Size: 34.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fletchr_uintn-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7677a72ef47edc37d08345bfb63734d311f6cd38db4109e80812291887e8766e
MD5 444577f596cad4b50a2a7c49b90507bd
BLAKE2b-256 d0f4d44c5b2e97445fae5b3fe9e010ef8a209f25cd9494ac522508cbc735b4f9

See more details on using hashes here.

File details

Details for the file fletchr_uintn-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: fletchr_uintn-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 23.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fletchr_uintn-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a576beffe77c16153457decad81e2bb7cda0f2372c530592478203cb871d5e3f
MD5 2e5a90169e854e0a9faeaf06ac525b64
BLAKE2b-256 ee2f3e142837d485e673974ab63d8d15bb1fc73688c72653b454a9f6ee6019d1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

0.0.2

2 files

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