Backports

Package: cbase.backports

C API backports that provide a uniform interface across Python versions. When the target Python provides the native API, the shim is a thin #define alias; otherwise a static inline fallback is compiled.

pylong — 128-bit Integer Backport

Module: cbase.backports.pylong

Bridges Python int ↔ 128-bit native integer types (uint128_t / int128_t). The native types cannot be represented directly in Cython (GCC __int128_t has no pxd representation), so the Python-level API works with 16-byte little-endian bytes buffers.

On GCC/Clang, uint128_t / int128_t map to __uint128_t / __int128_t. On MSVC (which lacks 128-bit integers), they are emulated as two-limb little-endian structs — byte-compatible with the GCC layout, so 16-byte buffers round-trip identically across compilers.

cbase.backports.pylong.pylong_as_int128(val) bytes
cbase.backports.pylong.pylong_as_uint128(val) bytes
cbase.backports.pylong.pylong_from_int128(bytes buf)
cbase.backports.pylong.pylong_from_uint128(bytes buf)

Usage

from cbase.backports.pylong import (
    pylong_from_uint128,
    pylong_as_uint128,
)

# bytes → Python int
val = pylong_from_uint128(b'\xff' * 16)
print(val)  # 340282366920938463463374607431768211455

# Python int → bytes (16-byte little-endian)
buf = pylong_as_uint128(42)
print(buf.hex())  # 2a0000000000000000000000000000

# Range constants
from cbase.backports.pylong import _UINT128_MAX, _INT128_MIN
print(_UINT128_MAX)  # 2**128 - 1
print(_INT128_MIN)   # -2**127

C-Level Interface

The header cbase/backports/pylong.h exposes these C functions (declared in cbase.backports.pylong.pxd for cimport):

from cbase.backports.pylong cimport (
    uint128_t, int128_t,
    c_read_uint128, c_write_uint128,
    PyLong_FromUInt128, PyLong_AsUInt128,
    c_u128_cmp,
)

Cross-Platform Design

#if defined(__SIZEOF_INT128__)
typedef __int128_t     int128_t;
typedef __uint128_t    uint128_t;
#else
// MSVC: two-limb little-endian struct
typedef struct { uint64_t lo; int64_t  hi; } int128_t;
typedef struct { uint64_t lo; uint64_t hi; } uint128_t;
#endif

Because the Cython boundary always converts via bytes (16-byte little-endian), the internal representation is opaque to Python code. This means 16-byte buffers produced on Linux (GCC __int128_t) can be consumed on Windows (MSVC struct) and vice versa.

pydict — Dict C API Backport

Module: cbase.backports.pydict

Backports PyDict_Pop (added in Python 3.13) for older Python versions.

C-Level Interface

from cbase.backports.pydict cimport BP_PyDict_Pop
int BP_PyDict_Pop(PyObject *op, PyObject *key, PyObject **result);

Returns 0 on success (key removed, *result is a new strong reference), 1 if the key is not present (*result is NULL), or -1 on error (exception set).

When PY_VERSION_HEX >= 0x030D0000, BP_PyDict_Pop is a #define alias for the native PyDict_Pop. On earlier versions, a static inline shim uses PyDict_GetItemWithError + PyDict_DelItem.

See also