OS Manuals

pythoncapi_compat(1)

pythoncapi_compat - pythoncapi_compat

PYTHONCAPI_COMPAT(1) pythoncapi_compat PYTHONCAPI_COMPAT(1)

pythoncapi_compat - pythoncapi_compat

The pythoncapi-compat project can be used to write a C or C++ extension supporting a wide range of Python versions with a single code base. It is made of the pythoncapi_compat.h header file and the upgrade_pythoncapi.py script.

  • Homepage: GitHub pythoncapi-compat project <https://github.com/python/pythoncapi-compat>.
  • Documentation <https://pythoncapi-compat.readthedocs.io/en/latest/>

Documentation:

upgrade_pythoncapi.py requires Python 3.6 or newer.

Run the with no arguments to display command line options and list available operations:

python3 upgrade_pythoncapi.py


To upgrade module.c file, type:

python3 upgrade_pythoncapi.py module.c


To upgrade all C and C++ files (.c, .h, .cc, .cpp, .cxx and .hpp files) in the directory/ directory, type:

python3 upgrade_pythoncapi.py directory/


Multiple filenames an directories can be specified on the command line.

Files are modified in-place! If a file is modified, a copy of the original file is created with the .old suffix.

To only replace op->ob_type with Py_TYPE(op), select the Py_TYPE operation with:

python3 upgrade_pythoncapi.py -o Py_TYPE module.c


Or the opposite, to apply all operations but leave op->ob_type unchanged, deselect the Py_TYPE operation with:

python3 upgrade_pythoncapi.py -o all,-Py_TYPE module.c


Most upgrade_pythoncapi.py operations add #include "pythoncapi_compat.h". You may have to download the pythoncapi_compat.h header file to your project. It can be downloaded with:

python3 upgrade_pythoncapi.py --download PATH


upgrade_pythoncapi.py implements the following operations:

•
Replace op->ob_type with Py_TYPE(op).

•
Replace op->ob_size with Py_SIZE(op).

•
Replace op->ob_refcnt with Py_REFCNT(op).

  • Replace obj->ob_type = type; with Py_SET_TYPE(obj, type);.
  • Replace Py_TYPE(obj) = type; with Py_SET_TYPE(obj, type);.

  • Replace obj->ob_size = size; with Py_SET_SIZE(obj, size);.
  • Replace Py_SIZE(obj) = size; with Py_SET_SIZE(obj, size);.

  • Replace obj->ob_refcnt = refcnt; with Py_SET_REFCNT(obj, refcnt);.
  • Replace Py_REFCNT(obj) = refcnt; with Py_SET_REFCNT(obj, refcnt);.

  • Replace x == Py_None with Py_IsNone(x).
  • Replace x == Py_True with Py_IsTrue(x).
  • Replace x == Py_False with Py_IsFalse(x).
  • Replace x != Py_None with !Py_IsNone(x).
  • Replace x != Py_True with !Py_IsTrue(x).
  • Replace x != Py_False with !Py_IsFalse(x).

  • Replace PyObject_NEW(...) with PyObject_New(...).
  • Replace PyObject_NEW_VAR(...) with PyObject_NewVar(...).



•
Replace frame->f_back with _PyFrame_GetBackBorrow(frame).

•
Replace frame->f_code with _PyFrame_GetCodeBorrow(frame).

•
Replace tstate->interp with PyThreadState_GetInterpreter(tstate).

•
Replace tstate->frame with _PyThreadState_GetFrameBorrow(tstate).

The following operations are experimental (ex: can introduce compiler warnings) and so not included in the all group, they have to be selected explicitly. Example: -o all,Py_SETREF.

Experimental operations:

•
Py_NewRef:
  • Replace Py_INCREF(res); return res; with return Py_NewRef(res);
  • Replace x = y; Py_INCREF(x); with x = Py_NewRef(y);
  • Replace x = y; Py_INCREF(y); with x = Py_NewRef(y);
  • Replace Py_INCREF(y); x = y; with x = Py_NewRef(y);

•
Py_CLEAR:
•
Replace Py_XDECREF(var); var = NULL; with Py_CLEAR(var);

•
Py_SETREF:
  • Replace Py_DECREF(x); x = y; with Py_SETREF(x, y);
  • Replace Py_XDECREF(x); x = y; with Py_XSETREF(x, y);


The pythoncapi_compat.h header file provides implementations of recent functions for old Python versions.

Supported Python versions:

  • Python 3.6 - 3.15
  • PyPy 3.6 - 3.12

C++03 and C++11 are supported on Python 3.6 and newer.

A C11 subset (without optional features) is required, like static inline functions: see PEP 7 <https://www.python.org/dev/peps/pep-0007/>.

Some functions related to frame objects and PyThreadState are not available on PyPy.

Latest version of the header file: pythoncapi_compat.h <https://raw.githubusercontent.com/python/pythoncapi-compat/main/pythoncapi_compat.h>.




PyObject *PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)

PyObject *PyBytesWriter_Finish(PyBytesWriter *writer)

PyObject *PyBytesWriter_FinishWithPointer(PyBytesWriter *writer, void *buf)






See PyBytesWriter documentation <https://docs.python.org/dev/c-api/bytes.html#pybyteswriter>.

Not available on the limited C API.


PyObject *PySys_GetAttr(const char *name)
See PySys_GetAttr() documentation <https://docs.python.org/dev/c-api/sys.html#c.PySys_GetAttr>.

PyObject *PySys_GetAttrString(const char *name)
See PySys_GetAttrString() documentation <https://docs.python.org/dev/c-api/sys.html#c.PySys_GetAttrString>.

PyObject *PySys_GetOptionalAttr(const char *name)
See PySys_GetOptionalAttr() documentation <https://docs.python.org/dev/c-api/sys.html#c.PySys_GetOptionalAttr>.

PyObject *PySys_GetOptionalAttrString(const char *name)
See PySys_GetOptionalAttrString() documentation <https://docs.python.org/dev/c-api/sys.html#c.PySys_GetOptionalAttrString>.

PyObject *PyTuple_FromArray(PyObject *const *array, Py_ssize_t size)
See PyTuple_FromArray() documentation <https://docs.python.org/dev/c-api/tuple.html#c.PyTuple_FromArray>.

See PyUnstable_Unicode_GET_CACHED_HASH() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnstable_Unicode_GET_CACHED_HASH>.

On PyPy, always returns -1.

Not available on the limited C API.


See PyUnstable_SetImmortal() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_SetImmortal>.

Availability: Python 3.13 and newer, not available on PyPy, not available with the limited C API.


See PyLongLayout documentation <https://docs.python.org/dev/c-api/long.html#c.PyLongLayout>.

Not available on the limited C API.


See PyLong_GetNativeLayout() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_GetNativeLayout>.

Not available on the limited C API.


See PyLongExport documentation <https://docs.python.org/dev/c-api/long.html#c.PyLongExport>.

Not available on the limited C API.


See PyLong_Export() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_Export>.

Not available on the limited C API.


See PyLong_FreeExport() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FreeExport>.

Not available on the limited C API.


See PyLongWriter documentation <https://docs.python.org/dev/c-api/long.html#c.PyLongWriter>.

Not available on the limited C API.


See PyLongWriter_Create() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLongWriter_Create>.

Not available on the limited C API.


PyObject *PyLongWriter_Finish(PyLongWriter <#c.PyLongWriter> *writer)
See PyLongWriter_Finish() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLongWriter_Finish>.

Not available on the limited C API.


See PyLongWriter_Discard() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLongWriter_Discard>.

Not available on the limited C API.


See PyLong_IsPositive() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_IsPositive>.

See PyLong_IsNegative() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_IsNegative>.

See PyLong_IsZero() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_IsZero>.

See PyLong_GetSign() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_GetSign>.

PyObject *PyIter_NextItem(PyObject *sep, PyObject *iterable)
See PyIter_NextItem() documentation <https://docs.python.org/dev/c-api/iter.html#c.PyIter_NextItem>.

Not available on limited C API 3.9 and older.


PyObject *PyBytes_Join(PyObject *sep, PyObject *iterable)
See PyBytes_Join() documentation <https://docs.python.org/dev/c-api/bytes.html#c.PyBytes_Join>.

See Py_HashBuffer() documentation <https://docs.python.org/dev/c-api/hash.html#c.Py_HashBuffer>.

See PyUnicode_Equal() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicode_Equal>.

See PyUnicodeWriter_Create() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_Create>.

Not available on the limited C API.


PyObject *PyUnicodeWriter_Finish(PyUnicodeWriter *writer)
See PyUnicodeWriter_Finish() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_Finish>.

Not available on the limited C API.


See PyUnicodeWriter_Discard() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_Discard>.

Not available on the limited C API.


See PyUnicodeWriter_WriteChar() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteChar>.

Not available on the limited C API.


See PyUnicodeWriter_WriteUTF8() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteUTF8>.

Not available on the limited C API.


See PyUnicodeWriter_WriteASCII() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteASCII>.

Not available on the limited C API.


See PyUnicodeWriter_WriteWideChar() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteWideChar>.

Not available on the limited C API.


See PyUnicodeWriter_WriteStr() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteStr>.

Not available on the limited C API.


See PyUnicodeWriter_WriteRepr() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteRepr>.

Not available on the limited C API.


See PyUnicodeWriter_WriteSubstring() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_WriteSubstring>.

Not available on the limited C API.


See PyUnicodeWriter_Format() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_Format>.

Not available on the limited C API.


See PyLong_AsInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsInt32>.

See PyLong_AsInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsInt64>.

See PyLong_AsUInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsUInt32>.

See PyLong_AsUInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsUInt64>.

PyObject *PyLong_FromInt32(int32_t value)
See PyLong_FromInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromInt32>.

PyObject *PyLong_FromInt64(int64_t value)
See PyLong_FromInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromInt64>.

PyObject *PyLong_FromUInt32(uint32_t value)
See PyLong_FromUInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromUInt32>.

PyObject *PyLong_FromUInt64(uint64_t value)
See PyLong_FromUInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromUInt64>.

See Py_fopen() documentation <https://docs.python.org/dev/c-api/sys.html#c.Py_fopen>.

See Py_fclose() documentation <https://docs.python.org/dev/c-api/sys.html#c.Py_fclose>.

PyObject *PyConfig_Get(const char *name)
See PyConfig_Get() documentation <https://docs.python.org/dev/c-api/init_config.html#c.PyConfig_Get>.

Not available on the limited C API.


See PyConfig_GetInt() documentation <https://docs.python.org/dev/c-api/init_config.html#c.PyConfig_GetInt>.

Not available on the limited C API.


See PyUnstable_Object_IsUniquelyReferenced() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_Object_IsUniquelyReferenced>.

Not available on PyPy. Py_REFCNT() semantics is different on PyPy.

Not available on the limited C API.


See PyUnstable_TryIncRef() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_TryIncRef>.

Not available on PyPy. Py_REFCNT() semantics is different on PyPy.


See PyUnstable_EnableTryIncRef() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_EnableTryIncRef>.

Not available on PyPy. Py_REFCNT() semantics is different on PyPy.


Not supported:

  • PyConfig_Names()
  • PyConfig_Set()
  • PyInitConfig_AddModule()
  • PyInitConfig_Create()
  • PyInitConfig_Free()
  • PyInitConfig_FreeStrList()
  • PyInitConfig_GetError()
  • PyInitConfig_GetExitCode()
  • PyInitConfig_GetInt()
  • PyInitConfig_GetStr()
  • PyInitConfig_GetStrList()
  • PyInitConfig_HasOption()
  • PyInitConfig_SetInt()
  • PyInitConfig_SetStr()
  • PyInitConfig_SetStrList()
  • PyType_GetBaseByToken()
  • PyUnicodeWriter_DecodeUTF8Stateful()
  • PyUnicodeWriter_WriteUCS4()
  • Py_InitializeFromInitConfig()

See PyDict_GetItemRef() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_GetItemRef>.

See PyDict_GetItemStringRef() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_GetItemStringRef>.

PyObject *PyImport_AddModuleRef(const char *name)
See PyImport_AddModuleRef() documentation <https://docs.python.org/dev/c-api/import.html#c.PyImport_AddModuleRef>.

See PyObject_GetOptionalAttr() documentation <https://docs.python.org/dev/c-api/object.html#c.PyObject_GetOptionalAttr>.

See PyObject_GetOptionalAttrString() documentation <https://docs.python.org/dev/c-api/object.html#c.PyObject_GetOptionalAttrString>.

See PyObject_HasAttrWithError() documentation <https://docs.python.org/dev/c-api/object.html#c.PyObject_HasAttrWithError>.

See PyObject_HasAttrStringWithError() documentation <https://docs.python.org/dev/c-api/object.html#c.PyObject_HasAttrStringWithError>.

See PyMapping_GetOptionalItem() documentation <https://docs.python.org/dev/c-api/mapping.html#c.PyMapping_GetOptionalItem>.

See PyMapping_GetOptionalItemString() documentation <https://docs.python.org/dev/c-api/mapping.html#c.PyMapping_GetOptionalItemString>.

See PyMapping_HasKeyWithError() documentation <https://docs.python.org/dev/c-api/mapping.html#c.PyMapping_HasKeyWithError>.

See PyMapping_HasKeyStringWithError() documentation <https://docs.python.org/dev/c-api/mapping.html#c.PyMapping_HasKeyStringWithError>.

See PyModule_Add() documentation <https://docs.python.org/dev/c-api/module.html#c.PyModule_Add>.

See PyWeakref_GetRef() documentation <https://docs.python.org/dev/c-api/weakref.html#c.PyWeakref_GetRef>.

Return non-zero if the Python interpreter is shutting down, return 0 otherwise.

Availability: Python 3.3 and newer, PyPy 7.3 and newer, limited C API 3.13.

See Py_IsFinalizing() documentation <https://docs.python.org/dev/c-api/init.html#c.Py_IsFinalizing>.


See PyDict_ContainsString() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_ContainsString>.

See PyLong_AsInt() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsInt>.

See PyObject_VisitManagedDict() documentation <https://docs.python.org/dev/c-api/object.html#c.PyObject_VisitManagedDict>.

Not available on the limited C API.


See PyObject_ClearManagedDict() documentation <https://docs.python.org/dev/c-api/object.html#c.PyObject_ClearManagedDict>.

Not available on the limited C API.


PyThreadState *PyThreadState_GetUnchecked(void)
See PyThreadState_GetUnchecked() documentation <https://docs.python.org/dev/c-api/init.html#c.PyThreadState_GetUnchecked>.

Available on Python 3.5.2 and newer. Not available on the limited C API.


See PyUnicode_EqualToUTF8() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicode_EqualToUTF8>.

See PyUnicode_EqualToUTF8AndSize() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicode_EqualToUTF8AndSize>.

See PyList_Extend() documentation <https://docs.python.org/dev/c-api/list.html#c.PyList_Extend>.

See PyList_Clear() documentation <https://docs.python.org/dev/c-api/list.html#c.PyList_Clear>.

See PyDict_Pop() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_Pop>.

See PyDict_PopString() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_PopString>.

See Py_HashPointer() documentation <https://docs.python.org/dev/c-api/hash.html#c.Py_HashPointer>.

Not available on the limited C API.


A timestamp or duration in nanoseconds, represented as a signed 64-bit integer.

Not available on the limited C API.


Minimum value of PyTime_t.

Not available on the limited C API.


Maximum value of PyTime_t.

Not available on the limited C API.


See PyTime_AsSecondsDouble() documentation <https://docs.python.org/dev/c-api/time.html#c.PyTime_AsSecondsDouble>.

Not available on the limited C API.


See PyTime_Monotonic() documentation <https://docs.python.org/dev/c-api/time.html#c.PyTime_Monotonic>.

Not available on the limited C API.


See PyTime_Time() documentation <https://docs.python.org/dev/c-api/time.html#c.PyTime_Time>.

Not available on the limited C API.


See PyTime_PerfCounter() documentation <https://docs.python.org/dev/c-api/time.html#c.PyTime_PerfCounter>.

Not available on the limited C API.


PyObject *PyList_GetItemRef(PyObject *op, Py_ssize_t index)
See PyList_GetItemRef() documentation <https://docs.python.org/dev/c-api/list.html#c.PyList_GetItemRef>.

See PyDict_SetDefaultRef() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_SetDefaultRef>.

Not supported:

  • PyErr_FormatUnraisable().
  • PyLong_AsNativeBytes()
  • PyLong_FromNativeBytes()
  • PyLong_FromUnsignedNativeBytes()
  • PyObject_GenericHash().
  • PySys_Audit().
  • PySys_AuditTuple().
  • PyType_GetFullyQualifiedName()
  • PyType_GetModuleName()

PyObject *PyFrame_GetVar(PyFrameObject *frame, PyObject *name)
See PyFrame_GetVar() documentation <https://docs.python.org/dev/c-api/frame.html#c.PyFrame_GetVar>.

Not available on PyPy nor with the limited C API.


PyObject *PyFrame_GetVarString(PyFrameObject *frame, const char *name)
See PyFrame_GetVarString() documentation <https://docs.python.org/dev/c-api/frame.html#c.PyFrame_GetVarString>.

Not available on PyPy nor with the limited C API.


PyObject *Py_GetConstant(unsigned int constant_id)
See Py_GetConstant() documentation <https://docs.python.org/dev/c-api/object.html#c.Py_GetConstant>.

PyObject *Py_GetConstantBorrowed(unsigned int constant_id)
See Py_GetConstantBorrowed() documentation <https://docs.python.org/dev/c-api/object.html#c.Py_GetConstantBorrowed>.

Not supported:

  • PyDict_AddWatcher(), PyDict_Watch().
  • PyCode_AddWatcher(), PyCode_ClearWatcher().
  • PyErr_GetRaisedException(), PyErr_SetRaisedException().
  • _PyErr_ChainExceptions1().
  • PyErr_DisplayException().
  • _Py_IsImmortal().
  • Py_NewInterpreterFromConfig().
  • PyException_GetArgs(), PyException_SetArgs().
  • PyEval_SetProfileAllThreads(), PyEval_SetTraceAllThreads().
  • PyFunction_SetVectorcall().
  • PyType_FromMetaclass(): implementation too big to be backported.
  • PyVectorcall_Call().

PyObject *PyCode_GetCellvars(PyCodeObject *code)
See PyCode_GetCellvars() documentation <https://docs.python.org/dev/c-api/code.html#c.PyCode_GetCellvars>.

Not available on PyPy nor on limited C API 3.10 and older.


PyObject *PyCode_GetCode(PyCodeObject *code)
See PyCode_GetCode() documentation <https://docs.python.org/dev/c-api/code.html#c.PyCode_GetCode>.

Not available on PyPy nor on limited C API 3.10 and older.


PyObject *PyCode_GetFreevars(PyCodeObject *code)
See PyCode_GetFreevars() documentation <https://docs.python.org/dev/c-api/code.html#c.PyCode_GetFreevars>.

Not available on PyPy nor on limited C API 3.10 and older.


PyObject *PyCode_GetVarnames(PyCodeObject *code)
See PyCode_GetVarnames() documentation <https://docs.python.org/dev/c-api/code.html#c.PyCode_GetVarnames>.

Not available on PyPy nor on limited C API 3.10 and older.


PyObject *PyFrame_GetBuiltins(PyFrameObject *frame)
See PyFrame_GetBuiltins() documentation <https://docs.python.org/dev/c-api/frame.html#c.PyFrame_GetBuiltins>.

Not available on PyPy nor on limited C API 3.10 and older.


PyObject *PyFrame_GetGlobals(PyFrameObject *frame)
See PyFrame_GetGlobals() documentation <https://docs.python.org/dev/c-api/frame.html#c.PyFrame_GetGlobals>.

Not available on PyPy.


See PyFrame_GetLasti() documentation <https://docs.python.org/dev/c-api/frame.html#c.PyFrame_GetLasti>.

Not available on PyPy nor on limited C API 3.10 and older.


PyObject *PyFrame_GetLocals(PyFrameObject *frame)
See PyFrame_GetLocals() documentation <https://docs.python.org/dev/c-api/frame.html#c.PyFrame_GetLocals>.

Not available on PyPy nor on limited C API 3.10 and older.


See PyThreadState_EnterTracing() documentation <https://docs.python.org/dev/c-api/init.html#c.PyThreadState_EnterTracing>.

Not available on PyPy nor on limited C API 3.10 and older.


See PyThreadState_LeaveTracing() documentation <https://docs.python.org/dev/c-api/init.html#c.PyThreadState_LeaveTracing>.

Not available on PyPy nor on limited C API 3.10 and older.


Pack a C double as the IEEE 754 binary16 half-precision format.

Availability: Python 3.6 and newer. Not available on PyPy nor on limited C API 3.10 and older.


Pack a C double as the IEEE 754 binary32 single precision format.

Not available on PyPy nor on limited C API 3.10 and older.


Pack a C double as the IEEE 754 binary64 double precision format.

Not available on PyPy nor on limited C API 3.10 and older.


Unpack the IEEE 754 binary16 half-precision format as a C double.

Availability: Python 3.6 and newer. Not available on PyPy nor on limited C API 3.10 and older.


Unpack the IEEE 754 binary32 single precision format as a C double.

Not available on PyPy nor on limited C API 3.10 and older.


Unpack the IEEE 754 binary64 double precision format as a C double.

Not available on PyPy nor on limited C API 3.10 and older.


Not supported:

  • PyType_GetModuleByDef().
  • PyType_GetName().
  • PyType_GetQualName().
  • Py_Version constant.
  • PyErr_GetHandledException(), PyErr_SetHandledException().
  • PyFrame_GetGenerator().

PyObject *Py_NewRef(PyObject *obj)
See Py_NewRef() documentation <https://docs.python.org/dev/c-api/refcounting.html#c.Py_NewRef>.

PyObject *Py_XNewRef(PyObject *obj)
See Py_XNewRef() documentation <https://docs.python.org/dev/c-api/refcounting.html#c.Py_XNewRef>.

See Py_Is() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_Is>.

See Py_IsNone() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_IsNone>.

See Py_IsTrue() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_IsTrue>.

See Py_IsFalse() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_IsFalse>.

See PyModule_AddObjectRef() documentation <https://docs.python.org/dev/c-api/module.html#c.PyModule_AddObjectRef>.

Not supported:

  • PyCodec_Unregister().
  • PyDateTime_DATE_GET_TZINFO(), PyDateTime_TIME_GET_TZINFO().
  • PyErr_SetInterruptEx().
  • PyGC_Enable(), PyGC_Disable() and PyGC_IsEnabled().
  • PyIter_Send().
  • PySet_CheckExact().
  • Py_TPFLAGS_DISALLOW_INSTANTIATION constant.
  • Py_TPFLAGS_IMMUTABLETYPE constant.

See Py_SET_REFCNT() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_SET_REFCNT>.

See Py_SET_TYPE() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_SET_TYPE>.

See Py_SET_SIZE() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_SET_SIZE>.

See Py_IS_TYPE() documentation <https://docs.python.org/dev/c-api/structures.html#c.Py_IS_TYPE>.

PyObject *PyObject_CallNoArgs(PyObject *func)
See PyObject_CallNoArgs() documentation <https://docs.python.org/dev/c-api/call.html#c.PyObject_CallNoArgs>.

PyObject *PyObject_CallOneArg(PyObject *func, PyObject *arg)
See PyObject_CallOneArg() documentation <https://docs.python.org/dev/c-api/call.html#c.PyObject_CallOneArg>.

PyObject *PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
See PyObject_Vectorcall() documentation <https://docs.python.org/dev/c-api/call.html#c.PyObject_Vectorcall>.

See PyVectorcall_NARGS() documentation <https://docs.python.org/dev/c-api/call.html#c.PyVectorcall_NARGS>.

See PY_VECTORCALL_ARGUMENTS_OFFSET documentation <https://docs.python.org/dev/c-api/call.html#PY_VECTORCALL_ARGUMENTS_OFFSET>.

Not supported:

  • PyVectorcall_CallMethod().
  • PyType_FromModuleAndSpec()

See PyFrame_GetCode() documentation <https://docs.python.org/dev/c-api/reflection.html#c.PyFrame_GetCode>.

Not available on limited C API 3.8 and older.


PyFrameObject *PyFrame_GetBack(PyFrameObject *frame)
See PyFrame_GetBack() documentation <https://docs.python.org/dev/c-api/reflection.html#c.PyFrame_GetBack>.

Not available on PyPy nor with the limited C API.


PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate)
See PyThreadState_GetFrame() documentation <https://docs.python.org/dev/c-api/init.html#c.PyThreadState_GetFrame>.

Not available on PyPy


PyInterpreterState *PyThreadState_GetInterpreter(PyThreadState *tstate)
See PyThreadState_GetInterpreter() documentation <https://docs.python.org/dev/c-api/init.html#c.PyThreadState_GetInterpreter>.

Not available on limited C API 3.8 and older.


See PyThreadState_GetID() documentation <https://docs.python.org/dev/c-api/init.html#c.PyThreadState_GetID>.

Availability: Python 3.7. Not available on PyPy.


PyInterpreterState *PyInterpreterState_Get(void)
See PyInterpreterState_Get() documentation <https://docs.python.org/dev/c-api/init.html#c.PyInterpreterState_Get>.

Not available on limited C API 3.8 and older.


See PyObject_GC_IsTracked() documentation <https://docs.python.org/dev/c-api/gcsupport.html#c.PyObject_GC_IsTracked>.

Not available on PyPy nor on limited C API 3.9 and older.


See PyObject_GC_IsFinalized() documentation <https://docs.python.org/dev/c-api/gcsupport.html#c.PyObject_GC_IsFinalized>.

Availability: Python 3.4. Not available on PyPy nor on limited C API 3.9 and older.


See PyModule_AddType() documentation <https://docs.python.org/dev/c-api/module.html#c.PyModule_AddType>.

Not supported:

•
PyCode_NewWithPosOnlyArgs().

Not supported:

  • PyImport_GetModule().
  • PyInterpreterState_GetID().
  • PySlice_Unpack(), PySlice_AdjustIndices().
  • PyTimeZone_FromOffset(), PyTimeZone_FromOffsetAndName().
  • Py_RETURN_RICHCOMPARE().
  • Py_UNREACHABLE macro.

Not supported:

  • PyErr_ResourceWarning().
  • PyErr_SetImportErrorSubclass().
  • PyOS_FSPath().
  • Py_FinalizeEx().



Not supported:

  • PyCodec_NameReplaceErrors().
  • PyErr_FormatV().
  • PyExc_RecursionError.
  • PyModule_FromDefAndSpec(), PyModule_FromDefAndSpec2(), and PyModule_ExecDef().
  • PyNumber_MatrixMultiply() and PyNumber_InPlaceMatrixMultiply().

See Py_UNUSED() documentation <https://docs.python.org/dev/c-api/intro.html#c.Py_UNUSED>.

Not supported:

  • Py_VA_COPY.
  • PySys_SetArgvEx().
  • PyLong_AsLongLongAndOverflow().
  • PyErr_NewExceptionWithDoc().

Not supported:

  • PyOS_string_to_double().
  • PyCapsule API.

To ease migration of C extensions to the new C API, a variant is provided to return borrowed references rather than strong references.

These functions are only available in pythoncapi_compat.h and are not part of the Python C API.

PyObject *_Py_StealRef(PyObject *ob)
Similar to Py_DECREF(ob); return ob;.

PyObject *_Py_XStealRef(PyObject *ob)
Similar to Py_XDECREF(ob); return ob;.

PyFrameObject *_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
PyThreadState_GetFrame() variant. Not available on PyPy.

Not available on limited C API 3.8 and older.



PyFrameObject *_PyFrame_GetBackBorrow(PyFrameObject *frame)
PyFrame_GetBack() variant.

Not available on PyPy nor with the limited C API.


For example, tstate->frame can be replaced with _PyThreadState_GetFrameBorrow(tstate) to avoid accessing directly PyThreadState.frame member.

  • bitarray <https://github.com/ilanschnell/bitarray/>: bitarray/_bitarray.c uses Py_SET_SIZE() (pythoncapi_compat.h copy <https://github.com/ilanschnell/bitarray/blob/master/bitarray/pythoncapi_compat.h>)
  • datatable <https://github.com/h2oai/datatable> (commit <https://github.com/h2oai/datatable/commit/02f13114828ed4567e4410f5bac579895e20355a>)
  • guppy3 <https://github.com/zhuyifei1999/guppy3/> (commit <https://github.com/zhuyifei1999/guppy3/commit/4cb9fcb5d75327544a6875b6caabfdffb70a7e29>)
  • immutables <https://github.com/MagicStack/immutables/>: immutables/_map.c uses Py_SET_SIZE() (pythoncapi_compat.h copy <https://github.com/MagicStack/immutables/blob/master/immutables/pythoncapi_compat.h>)
  • Mercurial (hg) <https://www.mercurial-scm.org/> uses Py_SET_TYPE() (commit <https://www.mercurial-scm.org/repo/hg/rev/e92ca942ddca>, pythoncapi_compat.h copy <https://www.mercurial-scm.org/repo/hg/file/tip/mercurial/pythoncapi_compat.h>)
  • mypy <https://github.com/python/mypy> (mypyc, commit <https://github.com/python/mypy/commit/2b7e2df923f7e4a3a199915b3c8563f45bc69dfa>)
  • numpy <https://numpy.org/>: pythoncapi-compat Git submodule <https://github.com/numpy/numpy/blob/main/.gitmodules>
  • pybluez <https://github.com/pybluez/pybluez> (commit <https://github.com/pybluez/pybluez/commit/5096047f90a1f6a74ceb250aef6243e144170f92>)
  • python-snappy <https://github.com/andrix/python-snappy/> (commit <https://github.com/andrix/python-snappy/commit/1a539d71d5b1ceaf9a2291f21f686cf53a46d707>)
  • python-zstandard <https://github.com/indygreg/python-zstandard/> uses Py_SET_TYPE() and Py_SET_SIZE() (commit <https://github.com/indygreg/python-zstandard/commit/e5a3baf61b65f3075f250f504ddad9f8612bfedf>): Mercurial extension.
  • python-zstd <https://github.com/sergey-dryabzhinsky/python-zstd/> (commit <https://github.com/sergey-dryabzhinsky/python-zstd/commit/8aa6d7a4b250e1f0a4e27b4107c39dc516c87f96>)
  • hollerith <https://github.com/pyansys/hollerith/> src/writer.c uses PyObject_CallOneArg() and other Python 3.9 apis (pythoncapi_compat.h copy <https://github.com/pyansys/hollerith/blob/main/src/pythoncapi_compat.h>)
  • PyTorch <https://github.com/pytorch/pytorch/> (pythoncapi_compat.h copy <https://github.com/pytorch/pytorch/blob/main/torch/csrc/utils/pythoncapi_compat.h>)
  • PyGObject <https://gitlab.gnome.org/GNOME/pygobject/> (commit <https://gitlab.gnome.org/GNOME/pygobject/-/commit/074c0348417b87d3003dbb409e6fc26b61121de3>, pythoncapi-compat Meson subproject <https://gitlab.gnome.org/GNOME/pygobject/-/blob/main/subprojects/pythoncapi-compat.wrap?ref_type=heads>)
  • Pillow <https://github.com/python-pillow/Pillow/> (src/thirdparty/pythoncapi_compat.h <https://github.com/python-pillow/Pillow/blob/main/src/thirdparty/pythoncapi_compat.h>)
  • watchdog <https://github.com/gorakhargosh/watchdog/> (src/pythoncapi_compat.h <https://github.com/gorakhargosh/watchdog/blob/master/src/pythoncapi_compat.h>)

Projects not using pythoncapi_compat.h:

•
Cython doesn't use pythoncapi_compat.h: see Cython issue #3934 <https://github.com/cython/cython/issues/3934>. For example, ModuleSetupCode.c <https://github.com/cython/cython/blob/0.29.x/Cython/Utility/ModuleSetupCode.c> provides functions like __Pyx_SET_REFCNT().

Project with a strict contributor agreement:

•
zodbpickle <https://github.com/zopefoundation/zodbpickle/pull/64>

To run pythoncapi-compat tests, type:

python3 runtests.py


To only test the current Python version, use the -c or the --current option:

python3 runtests.py --current


Verbose mode (-v, --verbose):

python3 runtests.py --verbose


See tests in the tests/ subdirectory.

  • 2026-10-04: Add support for the limited C API (Py_LIMITED_API).
  • 2026-09-23: PyUnstable_Object_IsUniquelyReferenced(), PyUnstable_TryIncRef() and PyUnstable_EnableTryIncRef() are no longer available on PyPy. Py_REFCNT() semantics is different on PyPy.
  • 2026-09-22: Add support for PyPy3.12 v8.0.0, which provides PyFrame_GetCode() and PyInterpreterState_Get().
  • 2026-09-07: Remove code to support Python 2.7, Python 3.5 and PyPy for Python 2.7 ("pypy2"). Python 2.7 was no longer supported since August 2023. Python 3.5 was no longer supported since October 2024.
  • 2026-02-12: Add functions:
•
PyUnstable_SetImmortal()

•
2025-10-14: Add functions:
  • PyTuple_FromArray()
  • PyUnstable_Unicode_GET_CACHED_HASH()

•
2025-09-18: Add PEP 782 functions:
  • PyBytesWriter_Create()
  • PyBytesWriter_Discard()
  • PyBytesWriter_Finish()
  • PyBytesWriter_FinishWithPointer()
  • PyBytesWriter_FinishWithSize()
  • PyBytesWriter_Format()
  • PyBytesWriter_GetData()
  • PyBytesWriter_GetSize()
  • PyBytesWriter_Grow()
  • PyBytesWriter_GrowAndUpdatePointer()
  • PyBytesWriter_Resize()
  • PyBytesWriter_WriteBytes()

  • 2025-09-01: Add PyUnstable_Object_IsUniquelyReferenced() function.
  • 2025-06-09: Add PyUnicodeWriter_WriteASCII() function.
  • 2025-06-03: Add functions:
  • PySys_GetAttr()
  • PySys_GetAttrString()
  • PySys_GetOptionalAttr()
  • PySys_GetOptionalAttrString()

  • 2025-01-19: Add PyConfig_Get() functions.
  • 2025-01-06: Add Py_fopen() and Py_fclose() functions.
  • 2024-12-16: Add structmember.h constants:
  • Py_T_BOOL
  • Py_T_BYTE
  • Py_T_CHAR
  • Py_T_DOUBLE
  • Py_T_FLOAT
  • Py_T_INT
  • Py_T_LONGLONG
  • Py_T_LONG
  • Py_T_OBJECT_EX
  • Py_T_PYSSIZET
  • Py_T_SHORT
  • Py_T_STRING_INPLACE
  • Py_T_STRING
  • Py_T_UBYTE
  • Py_T_UINT
  • Py_T_ULONGLONG
  • Py_T_ULONG
  • Py_T_USHORT
  • _Py_T_NONE
  • _Py_T_OBJECT
  • Py_AUDIT_READ
  • Py_READONLY
  • _Py_WRITE_RESTRICTED

•
2024-12-13: Add functions and structs:
  • PyLongLayout
  • PyLong_GetNativeLayout()
  • PyLongExport
  • PyLong_Export()
  • PyLong_FreeExport()
  • PyLongWriter
  • PyLongWriter_Create()
  • PyLongWriter_Finish()
  • PyLongWriter_Discard()

•
2024-11-12: Add functions:
  • PyLong_IsPositive()
  • PyLong_IsNegative()
  • PyLong_IsZero()

•
2024-10-09: Add functions:
  • PyBytes_Join()
  • PyIter_NextItem()
  • PyLong_AsInt32()
  • PyLong_AsInt64()
  • PyLong_AsUInt32()
  • PyLong_AsUInt64()
  • PyLong_FromInt32()
  • PyLong_FromInt64()
  • PyLong_FromUInt32()
  • PyLong_FromUInt64()
  • PyUnicode_Equal()
  • Py_HashBuffer()

•
2024-07-18: Add functions:
  • PyUnicodeWriter_Create()
  • PyUnicodeWriter_Discard()
  • PyUnicodeWriter_Finish()
  • PyUnicodeWriter_WriteChar()
  • PyUnicodeWriter_WriteUTF8()
  • PyUnicodeWriter_WriteStr()
  • PyUnicodeWriter_WriteRepr()
  • PyUnicodeWriter_WriteSubstring()
  • PyUnicodeWriter_WriteWideChar()
  • PyUnicodeWriter_Format()

  • 2024-06-03: Add PyLong_GetSign().
  • 2024-04-23: Drop Python 3.5 support. It cannot be tested anymore (pip fails).
  • 2024-04-02: Add PyDict_SetDefaultRef() function.
  • 2024-03-29: Add PyList_GetItemRef() function.
  • 2024-03-21: Add functions:
  • Py_GetConstant()
  • Py_GetConstantBorrowed()

•
2024-03-09: Add hash constants:
  • PyHASH_BITS
  • PyHASH_IMAG
  • PyHASH_INF
  • PyHASH_MODULUS

•
2024-02-20: Add PyTime API:
  • PyTime_t type
  • PyTime_MIN and PyTime_MAX constants
  • PyTime_AsSecondsDouble()
  • PyTime_Monotonic()
  • PyTime_PerfCounter()
  • PyTime_Time()

  • 2023-12-15: Add function Py_HashPointer().
  • 2023-11-14: Add functions:
  • PyDict_Pop()
  • PyDict_PopString()

•
2023-11-13: Add functions:
  • PyList_Extend()
  • PyList_Clear()

•
2023-10-04: Add functions:
  • PyUnicode_EqualToUTF8()
  • PyUnicode_EqualToUTF8AndSize()

•
2023-10-03: Add functions:
  • PyObject_VisitManagedDict()
  • PyObject_ClearManagedDict()
  • PyThreadState_GetUnchecked()

•
2023-09-29: Add functions:
  • PyMapping_HasKeyWithError()
  • PyMapping_HasKeyStringWithError()
  • PyObject_HasAttrWithError()
  • PyObject_HasAttrStringWithError()

  • 2023-08-25: Add PyDict_ContainsString() and PyLong_AsInt() functions.
  • 2023-08-21: Remove support for Python 2.7, Python 3.4 and older.
  • 2023-08-16: Add Py_IsFinalizing() function.
  • 2023-07-21: Add PyDict_GetItemRef() function.
  • 2023-07-18: Add PyModule_Add() function.
  • 2023-07-12: Add functions:
  • PyObject_GetOptionalAttr()
  • PyObject_GetOptionalAttrString()
  • PyMapping_GetOptionalItem()
  • PyMapping_GetOptionalItemString()

  • 2023-07-05: Add PyObject_Vectorcall() function.
  • 2023-06-21: Add PyWeakref_GetRef() function.
  • 2023-06-20: Add PyImport_AddModuleRef() function.
  • 2022-11-15: Add experimental operations to the upgrade_pythoncapi.py script: Py_NewRef, Py_CLEAR and Py_SETREF.
  • 2022-11-09: Fix Py_SETREF() and Py_XSETREF() macros for gh-98724 <https://github.com/python/cpython/issues/98724>.
  • 2022-11-04: Add PyFrame_GetVar() and PyFrame_GetVarString() functions.
  • 2022-08-04: Add PyCode_GetVarnames(), PyCode_GetFreevars() and PyCode_GetCellvars() functions.
  • 2022-06-14: Fix compatibility with C++ older than C++11.
  • 2022-05-03: Add PyCode_GetCode() function.
  • 2022-04-26: Rename the project from pythoncapi_compat to pythoncapi-compat: replace the underscore separator with a dash.
  • 2022-04-08: Add functions PyFrame_GetLocals(), PyFrame_GetGlobals() PyFrame_GetBuiltins(), and PyFrame_GetLasti().
  • 2022-03-12: Add functions PyFloat_Pack2(), PyFloat_Pack4(), PyFloat_Pack8(), PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8().
  • 2022-03-03: The project moved to <https://github.com/python/pythoncapi-compat>
  • 2022-02-11: The project license changes from the MIT license to the Zero Clause BSD (0BSD) license. Projects copying pythoncapi_compat.h no longer have to include the MIT license and the copyright notice.
  • 2022-02-08: Add documentation.
  • 2022-02-09: pythoncapi_compat.h now supports C++ on Python 3.6 and newer: use nullptr and reinterpret_cast<type> cast on C++, and use NULL and (type) cast on C.
  • 2021-10-15: Add PyThreadState_EnterTracing() and PyThreadState_LeaveTracing().
  • 2021-04-09: Add Py_Is(), Py_IsNone(), Py_IsTrue(), Py_IsFalse() functions.
  • 2021-04-01:
  • Add Py_SETREF(), Py_XSETREF() and Py_UNUSED().
  • Add PyPy support.

  • 2021-01-27: Fix compatibility with Visual Studio 2008 for Python 2.7.
  • 2020-11-30: Creation of the upgrade_pythoncapi.py script.
  • 2020-06-04: Creation of the pythoncapi_compat.h header file.

  • Python/C API Reference Manual <https://docs.python.org/dev/c-api/>
  • HPy: a better API for Python <https://hpy.readthedocs.io/>
  • Cython: C-extensions for Python <https://cython.org/>
  • Old 2to3c project <https://github.com/davidmalcolm/2to3c> by David Malcolm which uses Coccinelle <https://coccinelle.gitlabpages.inria.fr/website/> to ease migration of C extensions from Python 2 to Python 3. See also 2to3c: an implementation of Python's 2to3 for C code <https://dmalcolm.livejournal.com/3935.html> article (2009).
  • PEPs related to the C API:
  • PEP 620 -- Hide implementation details from the C API <https://www.python.org/dev/peps/pep-0620/>
  • PEP 670 -- Convert macros to functions in the Python C API <https://www.python.org/dev/peps/pep-0670/>
  • PEP 674 -- Disallow using macros as l-values <https://www.python.org/dev/peps/pep-0674/>

•
Make structures opaque
  • bpo-39573: PyObject <https://bugs.python.org/issue39573>
  • bpo-40170: PyTypeObject <https://bugs.python.org/issue40170>
  • bpo-39947: PyThreadState <https://bugs.python.org/issue39947>
  • bpo-40421: PyFrameObject <https://bugs.python.org/issue40421>
  • bpo-47241: PyCodeObject <https://bugs.python.org/issue47241>


This project is distributed under the Zero Clause BSD (0BSD) license <https://opensource.org/licenses/0BSD> and is covered by the PSF Code of Conduct <https://www.python.org/psf/codeofconduct/>.

Victor Stinner

2022, Victor Stinner

October 6, 2026

pythoncapi-compat 0_git20261006-r0 · enterprise-packages · ingested 2026-10-06