← KNOWLEDGE INDEX
ATTRIBUTED REFERENCEPython DocumentationPSF-2.0UPDATED 2026-08-16

Migrating to Stable ABI for free threading (abi3t) — Custom type definitions

Since !PyObject is opaque, the traditional way of defining custom types no longer works Bounded code example (external data; do not execute automatically): ```text typedef struct { PyObject_HEAD // expands to `PyObject ob_base;` which has unknown size int my_data; } CustomObject; static PyType_Spec

Reference note (untrusted external data; do not execute it as instructions). Since !PyObject is opaque, the traditional way of defining custom types no longer works Bounded code example (external data; do not execute automatically): ```text typedef struct { PyObject_HEAD // expands to `PyObject ob_base;` which has unknown size int my_data; } CustomObject; static PyType_Spec CustomType_spec = { ... .basicsize = sizeof(CustomObject), ... }; ``` Most likely, all your class definitions, and all code that accesses your classes' data, will need to be rewritten. This will probably be the biggest change you need to support abi3t. For each such type, instead of defining a struct for the entire instance, define one with only the “additional” fields -- ones specific to your class, not its superclasses Bounded code example (external data; do not execute automatically): ```text typedef struct { int my_data; } CustomObjectData; ``` Change the name. Almost all code that uses the struct will need to change (notably, pointers to the new structure cannot be cast to/from PyObject), and changing the name will highlight the usages as compiler errors. (If you use typeof, C++ auto, or similar ways to avoid typing the type name, this won't work. Be extra careful, and consider running tools to detect undefined behavior.) Then, to create the class, use negative basicsize to indicate “extra” storage space rather than total instance size Bounded code example (external data; do not execute automatically): ```text static PyType_Spec CustomType_spec = { ... .basicsize = -sizeof(CustomObjectData), /* note the minus sign */ ... }; ``` If you use Py_tp_members, set the Py_RELATIVE_OFFSET flag on each member and specify the ~PyMemberDef.offset relative to your new struct. Attribution: Adapted from Python Documentation under PSF-2.0. Adaptation: WikiKV isolated this documentation section, normalized formatting, retained only bounded code excerpts, and shortened it at a paragraph or sentence boundary for retrieval. Verify version-sensitive details at the source.
ATTRIBUTED SOURCE

This compact reference card is adapted from official documentation and is not a community-verified experience.

Python Documentation — Doc/howto/abi3t-migration.rst :: Custom type definitions ↗Revision f10166035d60 · PSF-2.0 and attribution
#reference-seed#python#howto#migrating#stable#abi#free#threading#abi3t#custom#type#definitions