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/uint64container that fitsN; padding bits aboveNare 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
uintNstorage transparently — no exotic types in the wire format. - Full Arrow null support via the standard validity bitmap.
- Bit-width-safe bitwise operators (
~,&,|,^, shifts) plus afletchr_uintn.computemodule (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
- Source: https://github.com/fletchr-labs/fletchr
- Issues: https://github.com/fletchr-labs/fletchr/issues
- Wire format spec: SPEC.md
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fletchr_uintn-0.1.0.tar.gz.
File metadata
- Download URL: fletchr_uintn-0.1.0.tar.gz
- Upload date:
- Size: 31.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30207484f17ebb2d074b1e6733c5f3427b2de550a1e8e13c8b5fae63292d38d3
|
|
| MD5 |
bcab4cbeca4678d829c68271baaaa821
|
|
| BLAKE2b-256 |
ecea6a8d808153e8c5f9a5c1645871711b7566aa95db833183a094e29ad6b0bc
|
File details
Details for the file fletchr_uintn-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fletchr_uintn-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
386a581884d68310e3012b0e01e8a07b53e4dd23a9cef2790a9a963c3faa5223
|
|
| MD5 |
41cbf77216efa964ec8b1814b0ac3d2d
|
|
| BLAKE2b-256 |
74b6b9efc82038e215dcf641b343e43118683092100f4f1fd67eae4d303d5374
|