PYTHONCAPI\_COMPAT(1) pythoncapi\_compat PYTHONCAPI\_COMPAT(1)

# [NAME](#NAME)

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 &lt;https://github.com/python/pythoncapi-compat&gt;.
- Documentation &lt;https://pythoncapi-compat.readthedocs.io/en/latest/&gt;

Documentation:

# [UPGRADE\_PYTHONCAPI.PY SCRIPT](#UPGRADE_PYTHONCAPI.PY_SCRIPT)

**upgrade\_pythoncapi.py** requires Python 3.6 or newer.

## [Usage](#Usage)

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

```
python3 upgrade_pythoncapi.py
```

## [Select files and directories](#Select_files_and_directories)

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.

## [Select operations](#Select_operations)

To only replace **op-&gt;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-&gt;ob\_type** unchanged, deselect the **Py\_TYPE** operation with:

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

## [Download pythoncapi\_compat.h](#Download_pythoncapi_compat.h)

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 Operations](#Upgrade_Operations)

**upgrade\_pythoncapi.py** implements the following operations:

## [Py\_TYPE](#Py_TYPE)

•

Replace **op-&gt;ob\_type** with **Py\_TYPE(op)**.

## [Py\_SIZE](#Py_SIZE)

•

Replace **op-&gt;ob\_size** with **Py\_SIZE(op)**.

## [Py\_REFCNT](#Py_REFCNT)

•

Replace **op-&gt;ob\_refcnt** with **Py\_REFCNT(op)**.

## [Py\_SET\_TYPE](#Py_SET_TYPE)

- Replace **obj-&gt;ob\_type = type;** with **Py\_SET\_TYPE(obj, type);**.
- Replace **Py\_TYPE(obj) = type;** with **Py\_SET\_TYPE(obj, type);**.

## [Py\_SET\_SIZE](#Py_SET_SIZE)

- Replace **obj-&gt;ob\_size = size;** with **Py\_SET\_SIZE(obj, size);**.
- Replace **Py\_SIZE(obj) = size;** with **Py\_SET\_SIZE(obj, size);**.

## [Py\_SET\_REFCNT](#Py_SET_REFCNT)

- Replace **obj-&gt;ob\_refcnt = refcnt;** with **Py\_SET\_REFCNT(obj, refcnt);**.
- Replace **Py\_REFCNT(obj) = refcnt;** with **Py\_SET\_REFCNT(obj, refcnt);**.

## [Py\_Is](#Py_Is)

- 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)**.

## [PyObject\_NEW](#PyObject_NEW)

- Replace **PyObject\_NEW(...)** with **PyObject\_New(...)**.
- Replace **PyObject\_NEW\_VAR(...)** with **PyObject\_NewVar(...)**.

## [PyMem\_MALLOC](#PyMem_MALLOC)

- Replace [**PyMem\_MALLOC(n)**](/man/enterprise-packages/pythoncapi-compat/PyMem_MALLOC.n) with [**PyMem\_Malloc(n)**](/man/enterprise-packages/pythoncapi-compat/PyMem_Malloc.n).
- Replace **PyMem\_REALLOC(ptr, n)** with **PyMem\_Realloc(ptr, n)**.
- Replace **PyMem\_FREE(ptr)**, **PyMem\_DEL(ptr)** and **PyMem\_Del(ptr)** . with [**PyMem\_Free(n)**](/man/enterprise-packages/pythoncapi-compat/PyMem_Free.n).

## [PyObject\_MALLOC](#PyObject_MALLOC)

- Replace [**PyObject\_MALLOC(n)**](/man/enterprise-packages/pythoncapi-compat/PyObject_MALLOC.n) with [**PyObject\_Malloc(n)**](/man/enterprise-packages/pythoncapi-compat/PyObject_Malloc.n).
- Replace **PyObject\_REALLOC(ptr, n)** with **PyObject\_Realloc(ptr, n)**.
- Replace **PyObject\_FREE(ptr)**, **PyObject\_DEL(ptr)** and **PyObject\_Del(ptr)** . with [**PyObject\_Free(n)**](/man/enterprise-packages/pythoncapi-compat/PyObject_Free.n).

## [PyFrame\_GetBack](#PyFrame_GetBack)

•

Replace **frame-&gt;f\_back** with **\_PyFrame\_GetBackBorrow(frame)**.

## [PyFrame\_GetCode](#PyFrame_GetCode)

•

Replace **frame-&gt;f\_code** with **\_PyFrame\_GetCodeBorrow(frame)**.

## [PyThreadState\_GetInterpreter](#PyThreadState_GetInterpreter)

•

Replace **tstate-&gt;interp** with **PyThreadState\_GetInterpreter(tstate)**.

## [PyThreadState\_GetFrame](#PyThreadState_GetFrame)

•

Replace **tstate-&gt;frame** with **\_PyThreadState\_GetFrameBorrow(tstate)**.

## [Experimental operations](#Experimental_operations)

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);**

# [PYTHONCAPI\_COMPAT.H API](#PYTHONCAPI_COMPAT.H_API)

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 &lt;https://www.python.org/dev/peps/pep-0007/&gt;.

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

Latest version of the header file: pythoncapi\_compat.h &lt;https://raw.githubusercontent.com/python/pythoncapi-compat/main/pythoncapi\_compat.h&gt;.

## [Python 3.15](#Python_3.15)

[**PyBytesWriter \*PyBytesWriter\_Create(Py\_ssize\_t size)**](#PyBytesWriter)

[**void \*PyBytesWriter\_GetData(PyBytesWriter \*writer)**](#void)

[**Py\_ssize\_t PyBytesWriter\_GetSize(PyBytesWriter \*writer)**](#Py_ssize_t)

**PyObject \*PyBytesWriter\_FinishWithSize(PyBytesWriter \*writer, Py\_ssize\_t size)**

**PyObject \*PyBytesWriter\_Finish(PyBytesWriter \*writer)**

**PyObject \*PyBytesWriter\_FinishWithPointer(PyBytesWriter \*writer, void \*buf)**

[**void PyBytesWriter\_Discard(PyBytesWriter \*writer)**](#void~2)

[**int PyBytesWriter\_Resize(PyBytesWriter \*writer, Py\_ssize\_t size)**](#int)

[**int PyBytesWriter\_Grow(PyBytesWriter \*writer, Py\_ssize\_t size)**](#int~2)

[**void \*PyBytesWriter\_GrowAndUpdatePointer(PyBytesWriter \*writer, Py\_ssize\_t size, void \*buf)**](#void~3)

[**int PyBytesWriter\_WriteBytes(PyBytesWriter \*writer, const void \*bytes, Py\_ssize\_t size)**](#int~3)

[**int PyBytesWriter\_Format(PyBytesWriter \*writer, const char \*format, ...)**](#int~4)

See PyBytesWriter documentation &lt;https://docs.python.org/dev/c-api/bytes.html#pybyteswriter&gt;.

Not available on the limited C API.

**PyObject \*PySys\_GetAttr(const char \*name)**

See PySys\_GetAttr() documentation &lt;https://docs.python.org/dev/c-api/sys.html#c.PySys\_GetAttr&gt;.

**PyObject \*PySys\_GetAttrString(const char \*name)**

See PySys\_GetAttrString() documentation &lt;https://docs.python.org/dev/c-api/sys.html#c.PySys\_GetAttrString&gt;.

**PyObject \*PySys\_GetOptionalAttr(const char \*name)**

See PySys\_GetOptionalAttr() documentation &lt;https://docs.python.org/dev/c-api/sys.html#c.PySys\_GetOptionalAttr&gt;.

**PyObject \*PySys\_GetOptionalAttrString(const char \*name)**

See PySys\_GetOptionalAttrString() documentation &lt;https://docs.python.org/dev/c-api/sys.html#c.PySys\_GetOptionalAttrString&gt;.

**PyObject \*PyTuple\_FromArray(PyObject \*const \*array, Py\_ssize\_t size)**

See PyTuple\_FromArray() documentation &lt;https://docs.python.org/dev/c-api/tuple.html#c.PyTuple\_FromArray&gt;.

[**Py\_hash\_t PyUnstable\_Unicode\_GET\_CACHED\_HASH(PyObject \*op)**](#Py_hash_t)

See PyUnstable\_Unicode\_GET\_CACHED\_HASH() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnstable\_Unicode\_GET\_CACHED\_HASH&gt;.

On PyPy, always returns **-1**.

Not available on the limited C API.

[**int PyUnstable\_SetImmortal(PyObject \*op)**](#int~5)

See PyUnstable\_SetImmortal() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyUnstable\_SetImmortal&gt;.

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

## [Python 3.14](#Python_3.14)

[**struct PyLongLayout**](#struct)

See PyLongLayout documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLongLayout&gt;.

Not available on the limited C API.

[**const PyLongLayout &lt;#c.PyLongLayout&gt; \*PyLong\_GetNativeLayout(void)**](#const)

See PyLong\_GetNativeLayout() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_GetNativeLayout&gt;.

Not available on the limited C API.

[**struct PyLongExport**](#struct~2)

See PyLongExport documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLongExport&gt;.

Not available on the limited C API.

[**int PyLong\_Export(PyObject \*obj, PyLongExport &lt;#c.PyLongExport&gt; \*export\_long)**](#int~6)

See PyLong\_Export() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_Export&gt;.

Not available on the limited C API.

[**void PyLong\_FreeExport(PyLongExport &lt;#c.PyLongExport&gt; \*export\_long)**](#void~4)

See PyLong\_FreeExport() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_FreeExport&gt;.

Not available on the limited C API.

[**struct PyLongWriter**](#struct~3)

See PyLongWriter documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLongWriter&gt;.

Not available on the limited C API.

[**PyLongWriter &lt;#c.PyLongWriter&gt; \*PyLongWriter\_Create(int negative, Py\_ssize\_t ndigits, void \*\*digits)**](#PyLongWriter)

See PyLongWriter\_Create() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLongWriter\_Create&gt;.

Not available on the limited C API.

**PyObject \*PyLongWriter\_Finish(PyLongWriter &lt;#c.PyLongWriter&gt; \*writer)**

See PyLongWriter\_Finish() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLongWriter\_Finish&gt;.

Not available on the limited C API.

[**void PyLongWriter\_Discard(PyLongWriter &lt;#c.PyLongWriter&gt; \*writer)**](#void~5)

See PyLongWriter\_Discard() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLongWriter\_Discard&gt;.

Not available on the limited C API.

[**int PyLong\_IsPositive(PyObject \*obj)**](#int~7)

See PyLong\_IsPositive() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_IsPositive&gt;.

[**int PyLong\_IsNegative(PyObject \*obj)**](#int~8)

See PyLong\_IsNegative() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_IsNegative&gt;.

[**int PyLong\_IsZero(PyObject \*obj)**](#int~9)

See PyLong\_IsZero() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_IsZero&gt;.

[**int PyLong\_GetSign(PyObject \*obj, int \*sign)**](#int~10)

See PyLong\_GetSign() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_GetSign&gt;.

**PyObject \*PyIter\_NextItem(PyObject \*sep, PyObject \*iterable)**

See PyIter\_NextItem() documentation &lt;https://docs.python.org/dev/c-api/iter.html#c.PyIter\_NextItem&gt;.

Not available on limited C API 3.9 and older.

**PyObject \*PyBytes\_Join(PyObject \*sep, PyObject \*iterable)**

See PyBytes\_Join() documentation &lt;https://docs.python.org/dev/c-api/bytes.html#c.PyBytes\_Join&gt;.

[**Py\_hash\_t Py\_HashBuffer(const void \*ptr, Py\_ssize\_t len)**](#Py_hash_t~2)

See Py\_HashBuffer() documentation &lt;https://docs.python.org/dev/c-api/hash.html#c.Py\_HashBuffer&gt;.

[**int PyUnicode\_Equal(PyObject \*str1, PyObject \*str2)**](#int~11)

See PyUnicode\_Equal() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicode\_Equal&gt;.

[**PyUnicodeWriter \*PyUnicodeWriter\_Create(Py\_ssize\_t length)**](#PyUnicodeWriter)

See PyUnicodeWriter\_Create() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_Create&gt;.

Not available on the limited C API.

**PyObject \*PyUnicodeWriter\_Finish(PyUnicodeWriter \*writer)**

See PyUnicodeWriter\_Finish() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_Finish&gt;.

Not available on the limited C API.

[**void PyUnicodeWriter\_Discard(PyUnicodeWriter \*writer)**](#void~6)

See PyUnicodeWriter\_Discard() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_Discard&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_WriteChar(PyUnicodeWriter \*writer, Py\_UCS4 ch)**](#int~12)

See PyUnicodeWriter\_WriteChar() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_WriteChar&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_WriteUTF8(PyUnicodeWriter \*writer, const char \*str, Py\_ssize\_t size)**](#int~13)

See PyUnicodeWriter\_WriteUTF8() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_WriteUTF8&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_WriteASCII(PyUnicodeWriter \*writer, const char \*str, Py\_ssize\_t size)**](#int~14)

See PyUnicodeWriter\_WriteASCII() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_WriteASCII&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_WriteWideChar(PyUnicodeWriter \*writer, const wchar\_t \*str, Py\_ssize\_t size)**](#int~15)

See PyUnicodeWriter\_WriteWideChar() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_WriteWideChar&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_WriteStr(PyUnicodeWriter \*writer, PyObject \*obj)**](#int~16)

See PyUnicodeWriter\_WriteStr() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_WriteStr&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_WriteRepr(PyUnicodeWriter \*writer, PyObject \*obj)**](#int~17)

See PyUnicodeWriter\_WriteRepr() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_WriteRepr&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_WriteSubstring(PyUnicodeWriter \*writer, PyObject \*str, Py\_ssize\_t start, Py\_ssize\_t end)**](#int~18)

See PyUnicodeWriter\_WriteSubstring() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_WriteSubstring&gt;.

Not available on the limited C API.

[**int PyUnicodeWriter\_Format(PyUnicodeWriter \*writer, const char \*format, ...)**](#int~19)

See PyUnicodeWriter\_Format() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter\_Format&gt;.

Not available on the limited C API.

[**int PyLong\_AsInt32(PyObject \*obj, int32\_t \*pvalue)**](#int~20)

See PyLong\_AsInt32() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_AsInt32&gt;.

[**int PyLong\_AsInt64(PyObject \*obj, int64\_t \*pvalue)**](#int~21)

See PyLong\_AsInt64() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_AsInt64&gt;.

[**int PyLong\_AsUInt32(PyObject \*obj, uint32\_t \*pvalue)**](#int~22)

See PyLong\_AsUInt32() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_AsUInt32&gt;.

[**int PyLong\_AsUInt64(PyObject \*obj, uint64\_t \*pvalue)**](#int~23)

See PyLong\_AsUInt64() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_AsUInt64&gt;.

**PyObject \*PyLong\_FromInt32(int32\_t value)**

See PyLong\_FromInt32() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_FromInt32&gt;.

**PyObject \*PyLong\_FromInt64(int64\_t value)**

See PyLong\_FromInt64() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_FromInt64&gt;.

**PyObject \*PyLong\_FromUInt32(uint32\_t value)**

See PyLong\_FromUInt32() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_FromUInt32&gt;.

**PyObject \*PyLong\_FromUInt64(uint64\_t value)**

See PyLong\_FromUInt64() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_FromUInt64&gt;.

[**FILE \*Py\_fopen(PyObject \*path, const char \*mode)**](#FILE)

See Py\_fopen() documentation &lt;https://docs.python.org/dev/c-api/sys.html#c.Py\_fopen&gt;.

[**int Py\_fclose(FILE \*file)**](#int~24)

See Py\_fclose() documentation &lt;https://docs.python.org/dev/c-api/sys.html#c.Py\_fclose&gt;.

**PyObject \*PyConfig\_Get(const char \*name)**

See PyConfig\_Get() documentation &lt;https://docs.python.org/dev/c-api/init\_config.html#c.PyConfig\_Get&gt;.

Not available on the limited C API.

[**int PyConfig\_GetInt(const char \*name, int \*value)**](#int~25)

See PyConfig\_GetInt() documentation &lt;https://docs.python.org/dev/c-api/init\_config.html#c.PyConfig\_GetInt&gt;.

Not available on the limited C API.

[**int PyUnstable\_Object\_IsUniquelyReferenced(PyObject \*op)**](#int~26)

See PyUnstable\_Object\_IsUniquelyReferenced() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyUnstable\_Object\_IsUniquelyReferenced&gt;.

Not available on PyPy. **Py\_REFCNT()** semantics is different on PyPy.

Not available on the limited C API.

[**int PyUnstable\_TryIncRef(PyObject \*op)**](#int~27)

See PyUnstable\_TryIncRef() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyUnstable\_TryIncRef&gt;.

Not available on PyPy. **Py\_REFCNT()** semantics is different on PyPy.

[**void PyUnstable\_EnableTryIncRef(PyObject \*op)**](#void~7)

See PyUnstable\_EnableTryIncRef() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyUnstable\_EnableTryIncRef&gt;.

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()**

## [Python 3.13](#Python_3.13)

[**int PyDict\_GetItemRef(PyObject \*p, PyObject \*key, PyObject \*\*result)**](#int~28)

See PyDict\_GetItemRef() documentation &lt;https://docs.python.org/dev/c-api/dict.html#c.PyDict\_GetItemRef&gt;.

[**int PyDict\_GetItemStringRef(PyObject \*p, const char \*key, PyObject \*\*result)**](#int~29)

See PyDict\_GetItemStringRef() documentation &lt;https://docs.python.org/dev/c-api/dict.html#c.PyDict\_GetItemStringRef&gt;.

**PyObject \*PyImport\_AddModuleRef(const char \*name)**

See PyImport\_AddModuleRef() documentation &lt;https://docs.python.org/dev/c-api/import.html#c.PyImport\_AddModuleRef&gt;.

[**int PyObject\_GetOptionalAttr(PyObject \*obj, PyObject \*attr\_name, PyObject \*\*result)**](#int~30)

See PyObject\_GetOptionalAttr() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyObject\_GetOptionalAttr&gt;.

[**int PyObject\_GetOptionalAttrString(PyObject \*obj, const char \*attr\_name, PyObject \*\*result)**](#int~31)

See PyObject\_GetOptionalAttrString() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyObject\_GetOptionalAttrString&gt;.

[**int PyObject\_HasAttrWithError(PyObject \*obj, PyObject \*attr\_name)**](#int~32)

See PyObject\_HasAttrWithError() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyObject\_HasAttrWithError&gt;.

[**int PyObject\_HasAttrStringWithError(PyObject \*obj, const char \*attr\_name)**](#int~33)

See PyObject\_HasAttrStringWithError() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyObject\_HasAttrStringWithError&gt;.

[**int PyMapping\_GetOptionalItem(PyObject \*obj, PyObject \*key, PyObject \*\*result)**](#int~34)

See PyMapping\_GetOptionalItem() documentation &lt;https://docs.python.org/dev/c-api/mapping.html#c.PyMapping\_GetOptionalItem&gt;.

[**int PyMapping\_GetOptionalItemString(PyObject \*obj, const char \*key, PyObject \*\*result)**](#int~35)

See PyMapping\_GetOptionalItemString() documentation &lt;https://docs.python.org/dev/c-api/mapping.html#c.PyMapping\_GetOptionalItemString&gt;.

[**int PyMapping\_HasKeyWithError(PyObject \*obj, PyObject \*key)**](#int~36)

See PyMapping\_HasKeyWithError() documentation &lt;https://docs.python.org/dev/c-api/mapping.html#c.PyMapping\_HasKeyWithError&gt;.

[**int PyMapping\_HasKeyStringWithError(PyObject \*obj, const char \*key)**](#int~37)

See PyMapping\_HasKeyStringWithError() documentation &lt;https://docs.python.org/dev/c-api/mapping.html#c.PyMapping\_HasKeyStringWithError&gt;.

[**int PyModule\_Add(PyObject \*module, const char \*name, PyObject \*value)**](#int~38)

See PyModule\_Add() documentation &lt;https://docs.python.org/dev/c-api/module.html#c.PyModule\_Add&gt;.

[**int PyWeakref\_GetRef(PyObject \*ref, PyObject \*\*pobj)**](#int~39)

See PyWeakref\_GetRef() documentation &lt;https://docs.python.org/dev/c-api/weakref.html#c.PyWeakref\_GetRef&gt;.

[**int Py\_IsFinalizing()**](#int~40)

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 &lt;https://docs.python.org/dev/c-api/init.html#c.Py\_IsFinalizing&gt;.

[**int PyDict\_ContainsString(PyObject \*p, const char \*key)**](#int~41)

See PyDict\_ContainsString() documentation &lt;https://docs.python.org/dev/c-api/dict.html#c.PyDict\_ContainsString&gt;.

[**int PyLong\_AsInt(PyObject \*obj)**](#int~42)

See PyLong\_AsInt() documentation &lt;https://docs.python.org/dev/c-api/long.html#c.PyLong\_AsInt&gt;.

[**int PyObject\_VisitManagedDict(PyObject \*obj, visitproc visit, void \*arg)**](#int~43)

See PyObject\_VisitManagedDict() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyObject\_VisitManagedDict&gt;.

Not available on the limited C API.

[**void PyObject\_ClearManagedDict(PyObject \*obj)**](#void~8)

See PyObject\_ClearManagedDict() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.PyObject\_ClearManagedDict&gt;.

Not available on the limited C API.

**PyThreadState \*PyThreadState\_GetUnchecked(void)**

See PyThreadState\_GetUnchecked() documentation &lt;https://docs.python.org/dev/c-api/init.html#c.PyThreadState\_GetUnchecked&gt;.

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

[**int PyUnicode\_EqualToUTF8(PyObject \*unicode, const char \*str)**](#int~44)

See PyUnicode\_EqualToUTF8() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicode\_EqualToUTF8&gt;.

[**int PyUnicode\_EqualToUTF8AndSize(PyObject \*unicode, const char \*str, Py\_ssize\_t size)**](#int~45)

See PyUnicode\_EqualToUTF8AndSize() documentation &lt;https://docs.python.org/dev/c-api/unicode.html#c.PyUnicode\_EqualToUTF8AndSize&gt;.

[**int PyList\_Extend(PyObject \*list, PyObject \*iterable)**](#int~46)

See PyList\_Extend() documentation &lt;https://docs.python.org/dev/c-api/list.html#c.PyList\_Extend&gt;.

[**int PyList\_Clear(PyObject \*list)**](#int~47)

See PyList\_Clear() documentation &lt;https://docs.python.org/dev/c-api/list.html#c.PyList\_Clear&gt;.

[**int PyDict\_Pop(PyObject \*dict, PyObject \*key, PyObject \*\*result)**](#int~48)

See PyDict\_Pop() documentation &lt;https://docs.python.org/dev/c-api/dict.html#c.PyDict\_Pop&gt;.

[**int PyDict\_PopString(PyObject \*dict, const char \*key, PyObject \*\*result)**](#int~49)

See PyDict\_PopString() documentation &lt;https://docs.python.org/dev/c-api/dict.html#c.PyDict\_PopString&gt;.

[**Py\_hash\_t Py\_HashPointer(const void \*ptr)**](#Py_hash_t~3)

See Py\_HashPointer() documentation &lt;https://docs.python.org/dev/c-api/hash.html#c.Py\_HashPointer&gt;.

Not available on the limited C API.

[**type PyTime\_t**](#type)

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

Not available on the limited C API.

[**PyTime\_t &lt;#c.PyTime\_t&gt; PyTime\_MIN**](#PyTime_t)

Minimum value of **PyTime\_t**.

Not available on the limited C API.

[**PyTime\_t &lt;#c.PyTime\_t&gt; PyTime\_MAX**](#PyTime_t~2)

Maximum value of **PyTime\_t**.

Not available on the limited C API.

[**double PyTime\_AsSecondsDouble(PyTime\_t &lt;#c.PyTime\_t&gt; t)**](#double)

See PyTime\_AsSecondsDouble() documentation &lt;https://docs.python.org/dev/c-api/time.html#c.PyTime\_AsSecondsDouble&gt;.

Not available on the limited C API.

[**int PyTime\_Monotonic(PyTime\_t &lt;#c.PyTime\_t&gt; \*result)**](#int~50)

See PyTime\_Monotonic() documentation &lt;https://docs.python.org/dev/c-api/time.html#c.PyTime\_Monotonic&gt;.

Not available on the limited C API.

[**int PyTime\_Time(PyTime\_t &lt;#c.PyTime\_t&gt; \*result)**](#int~51)

See PyTime\_Time() documentation &lt;https://docs.python.org/dev/c-api/time.html#c.PyTime\_Time&gt;.

Not available on the limited C API.

[**int PyTime\_PerfCounter(PyTime\_t &lt;#c.PyTime\_t&gt; \*result)**](#int~52)

See PyTime\_PerfCounter() documentation &lt;https://docs.python.org/dev/c-api/time.html#c.PyTime\_PerfCounter&gt;.

Not available on the limited C API.

**PyObject \*PyList\_GetItemRef(PyObject \*op, Py\_ssize\_t index)**

See PyList\_GetItemRef() documentation &lt;https://docs.python.org/dev/c-api/list.html#c.PyList\_GetItemRef&gt;.

[**int PyDict\_SetDefaultRef(PyObject \*d, PyObject \*key, PyObject \*default\_value, PyObject \*\*result)**](#int~53)

See PyDict\_SetDefaultRef() documentation &lt;https://docs.python.org/dev/c-api/dict.html#c.PyDict\_SetDefaultRef&gt;.

Not supported:

- **PyErr\_FormatUnraisable()**.
- **PyLong\_AsNativeBytes()**
- **PyLong\_FromNativeBytes()**
- **PyLong\_FromUnsignedNativeBytes()**
- **PyObject\_GenericHash()**.
- **PySys\_Audit()**.
- **PySys\_AuditTuple()**.
- **PyType\_GetFullyQualifiedName()**
- **PyType\_GetModuleName()**

## [Python 3.12](#Python_3.12)

**PyObject \*PyFrame\_GetVar(PyFrameObject \*frame, PyObject \*name)**

See PyFrame\_GetVar() documentation &lt;https://docs.python.org/dev/c-api/frame.html#c.PyFrame\_GetVar&gt;.

Not available on PyPy nor with the limited C API.

**PyObject \*PyFrame\_GetVarString(PyFrameObject \*frame, const char \*name)**

See PyFrame\_GetVarString() documentation &lt;https://docs.python.org/dev/c-api/frame.html#c.PyFrame\_GetVarString&gt;.

Not available on PyPy nor with the limited C API.

**PyObject \*Py\_GetConstant(unsigned int constant\_id)**

See Py\_GetConstant() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.Py\_GetConstant&gt;.

**PyObject \*Py\_GetConstantBorrowed(unsigned int constant\_id)**

See Py\_GetConstantBorrowed() documentation &lt;https://docs.python.org/dev/c-api/object.html#c.Py\_GetConstantBorrowed&gt;.

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()**.

## [Python 3.11](#Python_3.11)

**PyObject \*PyCode\_GetCellvars(PyCodeObject \*code)**

See PyCode\_GetCellvars() documentation &lt;https://docs.python.org/dev/c-api/code.html#c.PyCode\_GetCellvars&gt;.

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

**PyObject \*PyCode\_GetCode(PyCodeObject \*code)**

See PyCode\_GetCode() documentation &lt;https://docs.python.org/dev/c-api/code.html#c.PyCode\_GetCode&gt;.

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

**PyObject \*PyCode\_GetFreevars(PyCodeObject \*code)**

See PyCode\_GetFreevars() documentation &lt;https://docs.python.org/dev/c-api/code.html#c.PyCode\_GetFreevars&gt;.

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

**PyObject \*PyCode\_GetVarnames(PyCodeObject \*code)**

See PyCode\_GetVarnames() documentation &lt;https://docs.python.org/dev/c-api/code.html#c.PyCode\_GetVarnames&gt;.

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

**PyObject \*PyFrame\_GetBuiltins(PyFrameObject \*frame)**

See PyFrame\_GetBuiltins() documentation &lt;https://docs.python.org/dev/c-api/frame.html#c.PyFrame\_GetBuiltins&gt;.

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

**PyObject \*PyFrame\_GetGlobals(PyFrameObject \*frame)**

See PyFrame\_GetGlobals() documentation &lt;https://docs.python.org/dev/c-api/frame.html#c.PyFrame\_GetGlobals&gt;.

Not available on PyPy.

[**int PyFrame\_GetLasti(PyFrameObject \*frame)**](#int~54)

See PyFrame\_GetLasti() documentation &lt;https://docs.python.org/dev/c-api/frame.html#c.PyFrame\_GetLasti&gt;.

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

**PyObject \*PyFrame\_GetLocals(PyFrameObject \*frame)**

See PyFrame\_GetLocals() documentation &lt;https://docs.python.org/dev/c-api/frame.html#c.PyFrame\_GetLocals&gt;.

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

[**void PyThreadState\_EnterTracing(PyThreadState \*tstate)**](#void~9)

See PyThreadState\_EnterTracing() documentation &lt;https://docs.python.org/dev/c-api/init.html#c.PyThreadState\_EnterTracing&gt;.

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

[**void PyThreadState\_LeaveTracing(PyThreadState \*tstate)**](#void~10)

See PyThreadState\_LeaveTracing() documentation &lt;https://docs.python.org/dev/c-api/init.html#c.PyThreadState\_LeaveTracing&gt;.

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

[**int PyFloat\_Pack2(double x, unsigned char \*p, int le)**](#int~55)

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.

[**int PyFloat\_Pack4(double x, unsigned char \*p, int le)**](#int~56)

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.

[**int PyFloat\_Pack8(double x, unsigned char \*p, int le)**](#int~57)

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.

[**double PyFloat\_Unpack2(const unsigned char \*p, int le)**](#double~2)

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.

[**double PyFloat\_Unpack4(const unsigned char \*p, int le)**](#double~3)

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.

[**double PyFloat\_Unpack8(const unsigned char \*p, int le)**](#double~4)

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()**.

## [Python 3.10](#Python_3.10)

**PyObject \*Py\_NewRef(PyObject \*obj)**

See Py\_NewRef() documentation &lt;https://docs.python.org/dev/c-api/refcounting.html#c.Py\_NewRef&gt;.

**PyObject \*Py\_XNewRef(PyObject \*obj)**

See Py\_XNewRef() documentation &lt;https://docs.python.org/dev/c-api/refcounting.html#c.Py\_XNewRef&gt;.

[**int Py\_Is(PyObject \*x, PyObject \*y)**](#int~58)

See Py\_Is() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_Is&gt;.

[**int Py\_IsNone(PyObject \*x)**](#int~59)

See Py\_IsNone() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_IsNone&gt;.

[**int Py\_IsTrue(PyObject \*x)**](#int~60)

See Py\_IsTrue() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_IsTrue&gt;.

[**int Py\_IsFalse(PyObject \*x)**](#int~61)

See Py\_IsFalse() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_IsFalse&gt;.

[**int PyModule\_AddObjectRef(PyObject \*module, const char \*name, PyObject \*value)**](#int~62)

See PyModule\_AddObjectRef() documentation &lt;https://docs.python.org/dev/c-api/module.html#c.PyModule\_AddObjectRef&gt;.

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.

## [Python 3.9](#Python_3.9)

## [PyObject](#PyObject)

[**void Py\_SET\_REFCNT(PyObject \*ob, Py\_ssize\_t refcnt)**](#void~11)

See Py\_SET\_REFCNT() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_SET\_REFCNT&gt;.

[**void Py\_SET\_TYPE(PyObject \*ob, PyTypeObject \*type)**](#void~12)

See Py\_SET\_TYPE() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_SET\_TYPE&gt;.

[**void Py\_SET\_SIZE(PyVarObject \*ob, Py\_ssize\_t size)**](#void~13)

See Py\_SET\_SIZE() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_SET\_SIZE&gt;.

[**int Py\_IS\_TYPE(const PyObject \*ob, const PyTypeObject \*type)**](#int~63)

See Py\_IS\_TYPE() documentation &lt;https://docs.python.org/dev/c-api/structures.html#c.Py\_IS\_TYPE&gt;.

**PyObject \*PyObject\_CallNoArgs(PyObject \*func)**

See PyObject\_CallNoArgs() documentation &lt;https://docs.python.org/dev/c-api/call.html#c.PyObject\_CallNoArgs&gt;.

**PyObject \*PyObject\_CallOneArg(PyObject \*func, PyObject \*arg)**

See PyObject\_CallOneArg() documentation &lt;https://docs.python.org/dev/c-api/call.html#c.PyObject\_CallOneArg&gt;.

**PyObject \*PyObject\_Vectorcall(PyObject \*callable, PyObject \*const \*args, size\_t nargsf, PyObject \*kwnames)**

See PyObject\_Vectorcall() documentation &lt;https://docs.python.org/dev/c-api/call.html#c.PyObject\_Vectorcall&gt;.

[**Py\_ssize\_t PyVectorcall\_NARGS(size\_t nargsf)**](#Py_ssize_t~2)

See PyVectorcall\_NARGS() documentation &lt;https://docs.python.org/dev/c-api/call.html#c.PyVectorcall\_NARGS&gt;.

[**PY\_VECTORCALL\_ARGUMENTS\_OFFSET**](#PY_VECTORCALL_ARGUMENTS_OFFSET)

See PY\_VECTORCALL\_ARGUMENTS\_OFFSET documentation &lt;https://docs.python.org/dev/c-api/call.html#PY\_VECTORCALL\_ARGUMENTS\_OFFSET&gt;.

Not supported:

- **PyVectorcall\_CallMethod()**.
- **PyType\_FromModuleAndSpec()**

## [PyFrameObject](#PyFrameObject)

[**PyCodeObject \*PyFrame\_GetCode(PyFrameObject \*frame)**](#PyCodeObject)

See PyFrame\_GetCode() documentation &lt;https://docs.python.org/dev/c-api/reflection.html#c.PyFrame\_GetCode&gt;.

Not available on limited C API 3.8 and older.

**PyFrameObject \*PyFrame\_GetBack(PyFrameObject \*frame)**

See PyFrame\_GetBack() documentation &lt;https://docs.python.org/dev/c-api/reflection.html#c.PyFrame\_GetBack&gt;.

Not available on PyPy nor with the limited C API.

## [PyThreadState](#PyThreadState)

**PyFrameObject \*PyThreadState\_GetFrame(PyThreadState \*tstate)**

See PyThreadState\_GetFrame() documentation &lt;https://docs.python.org/dev/c-api/init.html#c.PyThreadState\_GetFrame&gt;.

Not available on PyPy

**PyInterpreterState \*PyThreadState\_GetInterpreter(PyThreadState \*tstate)**

See PyThreadState\_GetInterpreter() documentation &lt;https://docs.python.org/dev/c-api/init.html#c.PyThreadState\_GetInterpreter&gt;.

Not available on limited C API 3.8 and older.

[**uint64\_t PyThreadState\_GetID(PyThreadState \*tstate)**](#uint64_t)

See PyThreadState\_GetID() documentation &lt;https://docs.python.org/dev/c-api/init.html#c.PyThreadState\_GetID&gt;.

Availability: Python 3.7. Not available on PyPy.

## [PyInterpreterState](#PyInterpreterState)

**PyInterpreterState \*PyInterpreterState\_Get(void)**

See PyInterpreterState\_Get() documentation &lt;https://docs.python.org/dev/c-api/init.html#c.PyInterpreterState\_Get&gt;.

Not available on limited C API 3.8 and older.

## [GC protocol](#GC_protocol)

[**int PyObject\_GC\_IsTracked(PyObject \*obj)**](#int~64)

See PyObject\_GC\_IsTracked() documentation &lt;https://docs.python.org/dev/c-api/gcsupport.html#c.PyObject\_GC\_IsTracked&gt;.

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

[**int PyObject\_GC\_IsFinalized(PyObject \*obj)**](#int~65)

See PyObject\_GC\_IsFinalized() documentation &lt;https://docs.python.org/dev/c-api/gcsupport.html#c.PyObject\_GC\_IsFinalized&gt;.

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

## [Module helper](#Module_helper)

[**int PyModule\_AddType(PyObject \*module, PyTypeObject \*type)**](#int~66)

See PyModule\_AddType() documentation &lt;https://docs.python.org/dev/c-api/module.html#c.PyModule\_AddType&gt;.

## [Python 3.8](#Python_3.8)

Not supported:

•

**PyCode\_NewWithPosOnlyArgs()**.

## [Python 3.7](#Python_3.7)

Not supported:

- **PyImport\_GetModule()**.
- **PyInterpreterState\_GetID()**.
- **PySlice\_Unpack()**, **PySlice\_AdjustIndices()**.
- **PyTimeZone\_FromOffset()**, **PyTimeZone\_FromOffsetAndName()**.
- **Py\_RETURN\_RICHCOMPARE()**.
- **Py\_UNREACHABLE** macro.

## [Python 3.6](#Python_3.6)

Not supported:

- **PyErr\_ResourceWarning()**.
- **PyErr\_SetImportErrorSubclass()**.
- **PyOS\_FSPath()**.
- **Py\_FinalizeEx()**.

## [Python 3.5.2](#Python_3.5.2)

[**Py\_SETREF(op, op2)**](#Py_SETREF%28op,)

[**Py\_XSETREF(op, op2)**](#Py_XSETREF%28op,)

Not supported:

- **PyCodec\_NameReplaceErrors()**.
- **PyErr\_FormatV()**.
- **PyExc\_RecursionError**.
- **PyModule\_FromDefAndSpec()**, **PyModule\_FromDefAndSpec2()**, and **PyModule\_ExecDef()**.
- **PyNumber\_MatrixMultiply()** and **PyNumber\_InPlaceMatrixMultiply()**.

## [Python 3.4](#Python_3.4)

[**Py\_UNUSED(name)**](#Py_UNUSED%28name%29)

See Py\_UNUSED() documentation &lt;https://docs.python.org/dev/c-api/intro.html#c.Py\_UNUSED&gt;.

## [Python 3.2](#Python_3.2)

Not supported:

- **Py\_VA\_COPY**.
- **PySys\_SetArgvEx()**.
- **PyLong\_AsLongLongAndOverflow()**.
- **PyErr\_NewExceptionWithDoc()**.

## [Python 3.1](#Python_3.1)

Not supported:

- **PyOS\_string\_to\_double()**.
- **PyCapsule** API.

## [Borrow variant](#Borrow_variant)

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.

[**PyCodeObject \*\_PyFrame\_GetCodeBorrow(PyFrameObject \*frame)**](#PyCodeObject~2)

**PyFrame\_GetCode()** variant.

**PyFrameObject \*\_PyFrame\_GetBackBorrow(PyFrameObject \*frame)**

**PyFrame\_GetBack()** variant.

Not available on PyPy nor with the limited C API.

For example, **tstate-&gt;frame** can be replaced with **\_PyThreadState\_GetFrameBorrow(tstate)** to avoid accessing directly **PyThreadState.frame** member.

# [PYTHONCAPI-COMPAT USERS](#PYTHONCAPI-COMPAT_USERS)

## [Examples of projects using pythoncapi\_compat.h](#Examples_of_projects_using_pythoncapi_compat.h)

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

## [Projects not using pythoncapi\_compat.h](#Projects_not_using_pythoncapi_compat.h)

Projects not using **pythoncapi\_compat.h**:

•

Cython doesn't use pythoncapi\_compat.h: see Cython issue #3934 &lt;https://github.com/cython/cython/issues/3934&gt;. For example, ModuleSetupCode.c &lt;https://github.com/cython/cython/blob/0.29.x/Cython/Utility/ModuleSetupCode.c&gt; provides functions like **\_\_Pyx\_SET\_REFCNT()**.

Project with a strict contributor agreement:

•

zodbpickle &lt;https://github.com/zopefoundation/zodbpickle/pull/64&gt;

# [RUN TESTS](#RUN_TESTS)

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.

# [CHANGELOG](#CHANGELOG)

- 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()**

<!--THE END-->

- 2025-09-01: Add **PyUnstable\_Object\_IsUniquelyReferenced()** function.
- 2025-06-09: Add **PyUnicodeWriter\_WriteASCII()** function.
- 2025-06-03: Add functions:

<!--THE END-->

- **PySys\_GetAttr()**
- **PySys\_GetAttrString()**
- **PySys\_GetOptionalAttr()**
- **PySys\_GetOptionalAttrString()**

<!--THE END-->

- 2025-01-19: Add **PyConfig\_Get()** functions.
- 2025-01-06: Add **Py\_fopen()** and **Py\_fclose()** functions.
- 2024-12-16: Add **structmember.h** constants:

<!--THE END-->

- **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()**

<!--THE END-->

- 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:

<!--THE END-->

- **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()**

<!--THE END-->

- 2023-12-15: Add function **Py\_HashPointer()**.
- 2023-11-14: Add functions:

<!--THE END-->

- **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()**

<!--THE END-->

- 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:

<!--THE END-->

- **PyObject\_GetOptionalAttr()**
- **PyObject\_GetOptionalAttrString()**
- **PyMapping\_GetOptionalItem()**
- **PyMapping\_GetOptionalItemString()**

<!--THE END-->

- 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 &lt;https://github.com/python/cpython/issues/98724&gt;.
- 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 &lt;https://github.com/python/pythoncapi-compat&gt;
- 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&lt;type&gt;** 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:

<!--THE END-->

- Add **Py\_SETREF()**, **Py\_XSETREF()** and **Py\_UNUSED()**.
- Add PyPy support.

<!--THE END-->

- 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.

# [LINKS](#LINKS)

- Python/C API Reference Manual &lt;https://docs.python.org/dev/c-api/&gt;
- HPy: a better API for Python &lt;https://hpy.readthedocs.io/&gt;
- Cython: C-extensions for Python &lt;https://cython.org/&gt;
- Old 2to3c project &lt;https://github.com/davidmalcolm/2to3c&gt; by David Malcolm which uses Coccinelle &lt;https://coccinelle.gitlabpages.inria.fr/website/&gt; to ease migration of C extensions from Python 2 to Python 3. See also 2to3c: an implementation of Python's 2to3 for C code &lt;https://dmalcolm.livejournal.com/3935.html&gt; article (2009).
- PEPs related to the C API:

<!--THE END-->

- PEP 620 -- Hide implementation details from the C API &lt;https://www.python.org/dev/peps/pep-0620/&gt;
- PEP 670 -- Convert macros to functions in the Python C API &lt;https://www.python.org/dev/peps/pep-0670/&gt;
- PEP 674 -- Disallow using macros as l-values &lt;https://www.python.org/dev/peps/pep-0674/&gt;

•

Make structures opaque

- bpo-39573: PyObject &lt;https://bugs.python.org/issue39573&gt;
- bpo-40170: PyTypeObject &lt;https://bugs.python.org/issue40170&gt;
- bpo-39947: PyThreadState &lt;https://bugs.python.org/issue39947&gt;
- bpo-40421: PyFrameObject &lt;https://bugs.python.org/issue40421&gt;
- bpo-47241: PyCodeObject &lt;https://bugs.python.org/issue47241&gt;

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

# [Author](#Author)

Victor Stinner

# [Copyright](#Copyright)

2022, Victor Stinner

October 6, 2026

---

Document: pythoncapi_compat(1) from pythoncapi-compat 0_git20261006-r0 (Chainguard OS)
Source: https://github.com/python/pythoncapi-compat.git
