对象协议

PyObject *Py_GetConstant(unsigned int constant_id)
属于 稳定 ABI 自 3.13 版起.

获取一个指向常量的 strong reference

如果 constant_id 无效则设置一个异常并返回 NULL

constant_id 必须是下列常量标识符之一:

常量标识符

返回的对象

Py_CONSTANT_NONE

0

None

Py_CONSTANT_FALSE

1

False

Py_CONSTANT_TRUE

2

True

Py_CONSTANT_ELLIPSIS

3

Ellipsis

Py_CONSTANT_NOT_IMPLEMENTED

4

NotImplemented

Py_CONSTANT_ZERO

5

0

Py_CONSTANT_ONE

6

1

Py_CONSTANT_EMPTY_STR

7

''

Py_CONSTANT_EMPTY_BYTES

8

b''

Py_CONSTANT_EMPTY_TUPLE

9

()

仅对无法使用常量标识符的项目才会给出数字值。

Added in version 3.13.

在 CPython 中,所有这些常量都属于 immortal 对象。

PyObject *Py_GetConstantBorrowed(unsigned int constant_id)
属于 稳定 ABI 自 3.13 版起.

类似于 Py_GetConstant(),但会返回一个 borrowed reference

此函数的主要目的是用于向下兼容:对于新代码推荐使用 Py_GetConstant()

该引用是从解释器借入的,并将保持可用直到解释器最终化。

Added in version 3.13.

PyObject *Py_NotImplemented

NotImplemented 单例,用于标记某个操作没有针对给定类型组合的实现。

Py_RETURN_NOTIMPLEMENTED

正确处理从 C 函数内部返回 Py_NotImplemented 的问题(即新建一个指向 NotImplementedstrong reference 并返回它)。

Py_PRINT_RAW

要与多个打印对象的函数 (如 PyObject_Print()PyFile_WriteObject()) 一起使用的旗标。如果传入,这些函数应当使用对象的 str() 而不是 repr()

int PyObject_Print(PyObject *o, FILE *fp, int flags)

打印对象 o 到文件 fp。出错时返回 -1。flags 参数被用于启用特定的打印选项。目前唯一支持的选项是 Py_PRINT_RAW;如果给出该选项,则将写入对象的 str() 而不是 repr()

void PyObject_Dump(PyObject *op)

Dump an object op to stderr. This should only be used for debugging.

The output is intended to try dumping objects even after memory corruption:

  • Information is written starting with fields that are the least likely to crash when accessed.

  • This function can be called without an attached thread state, but it's not recommended to do so: it can cause deadlocks.

  • An object that does not belong to the current interpreter may be dumped, but this may also cause crashes or unintended behavior.

  • Implement a heuristic to detect if the object memory has been freed. Don't display the object contents in this case, only its memory address.

  • The output format may change at any time.

Example of output:

object address  : 0x7f80124702c0
object refcount : 2
object type     : 0x9902e0
object type name: str
object repr     : 'abcdef'

Added in version 3.15.

int PyObject_HasAttrWithError(PyObject *o, PyObject *attr_name)
属于 稳定 ABI 自 3.13 版起.

如果 o 具有属性 attr_name 则返回 1,否则返回 0。这相当于 Python 表达式 hasattr(o, attr_name)。当失败时,将返回 -1

Added in version 3.13.

int PyObject_HasAttrStringWithError(PyObject *o, const char *attr_name)
属于 稳定 ABI 自 3.13 版起.

这与 PyObject_HasAttrWithError() 相同,但 attr_name 被指定为 const char* UTF-8 编码的字节串,而不是 PyObject*

Added in version 3.13.

int PyObject_HasAttr(PyObject *o, PyObject *attr_name)
属于 稳定 ABI.

如果 o 具有属性 attr_name 则返回 1,否则返回 0。此函数总是会成功执行。

备注

当其调用 __getattr__()__getattribute__() 方法时发生的异常将不会被传播,而是交给 sys.unraisablehook()。想要进行适当的错误处理,请改用 PyObject_HasAttrWithError(), PyObject_GetOptionalAttr()PyObject_GetAttr().

int PyObject_HasAttrString(PyObject *o, const char *attr_name)
属于 稳定 ABI.

这与 PyObject_HasAttr() 相同,但 attr_name 被指定为 const char* UTF-8 编码的字节串,而不是 PyObject*

备注

在其调用 __getattr__()__getattribute__() 方法或创建临时 str 对象期间发生的异常将被静默地忽略。想要进行适当的错误处理,请改用 PyObject_HasAttrStringWithError(), PyObject_GetOptionalAttrString()PyObject_GetAttrString()

PyObject *PyObject_GetAttr(PyObject *o, PyObject *attr_name)
返回值:新的引用。 属于 稳定 ABI.

从对象 o 中读取名为 attr_name 的属性。成功返回属性值,失败则返回 NULL。这相当于 Python 表达式 o.attr_name.

如果缺少属性不应被视为执行失败,你可以改用 PyObject_GetOptionalAttr()

PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)
返回值:新的引用。 属于 稳定 ABI.

这与 PyObject_GetAttr() 相同,但 attr_name 被指定为 const char* UTF-8 编码的字节串,而不是 PyObject*

如果缺少属性不应被视为执行失败,你可以改用 PyObject_GetOptionalAttrString()

int PyObject_GetOptionalAttr(PyObject *obj, PyObject *attr_name, PyObject **result);
属于 稳定 ABI 自 3.13 版起.

PyObject_GetAttr() 的变化形式,它在未找到属性时不会引发 AttributeError

如果找到该属性,则返回 1 并将 *result 设为指向该属性的新 strong reference。如果未找到该属性,则返回 0 并将 *result 设为 NULLAttributeError 会被静默。如果引发了 AttributeError 以外的错误,则返回 -1 并将 *result 设为 NULL

Added in version 3.13.

int PyObject_GetOptionalAttrString(PyObject *obj, const char *attr_name, PyObject **result);
属于 稳定 ABI 自 3.13 版起.

这与 PyObject_GetOptionalAttr() 相同,但 attr_name 被指定为 const char* UTF-8 编码的字节串,而不是 PyObject*

Added in version 3.13.

PyObject *PyObject_GenericGetAttr(PyObject *o, PyObject *name)
返回值:新的引用。 属于 稳定 ABI.

通用的属性获取函数,用于放入类型对象的 tp_getattro 槽中。它在类的字典中(位于对象的 MRO 中)查找某个描述符,并在对象的 __dict__ 中查找某个属性。正如 实现描述器 所述,数据描述符优先于实例属性,而非数据描述符则不优先。失败则会触发 AttributeError

int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)
属于 稳定 ABI.

将对象 o 中名为 attr_name 的属性值设为 v 。失败时引发异常并返回 -1;成功时返回 0。这相当于 Python 语句 o.attr_name = v

如果 vNULL,该属性将被删除。此行为已被弃用而应改用 PyObject_DelAttr(),但目前还没有移除它的计划。

The function must not be called with a NULL v and an exception set. This case can arise from forgetting NULL checks and would delete the attribute.

在 3.15 版本发生变更: Must not be called with NULL value if an exception is set.

int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
属于 稳定 ABI.

这与 PyObject_SetAttr() 相同,但 attr_name 被指定为 const char* UTF-8 编码的字节串,而不是 PyObject*

如果 vNULL,该属性将被删除,但是此功能已被弃用而应改用 PyObject_DelAttrString()

The function must not be called with a NULL v and an exception set. This case can arise from forgetting NULL checks and would delete the attribute.

传给该函数的不同属性名称应当保持在较少的数量,通常是通过使用静态分配的字符串作为 attr_name 来做到这一点。对于编译时未知的属性名称,建议直接调用 PyUnicode_FromString()PyObject_SetAttr()。更多相关细节,请参阅 PyUnicode_InternFromString(),它可在内部用于创建键对象。

在 3.15 版本发生变更: Must not be called with NULL value if an exception is set.

int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)
属于 稳定 ABI.

通用的属性设置和删除函数,用于放入类型对象的 tp_setattro 槽。它在类的字典中(位于对象的 MRO 中)查找数据描述器,如果找到,则将比在实例字典中设置或删除属性优先执行。否则,该属性将在对象的 __dict__ 中设置或删除。如果成功将返回 0,否则将引发 AttributeError 并返回 -1

int PyObject_DelAttr(PyObject *o, PyObject *attr_name)
属于 稳定 ABI 自 3.13 版起.

删除对象 o 中名为 attr_name 的属性。失败时返回 -1。这相当于 Python 语句 del o.attr_name.

int PyObject_DelAttrString(PyObject *o, const char *attr_name)
属于 稳定 ABI 自 3.13 版起.

这与 PyObject_DelAttr() 相同,但 attr_name 被指定为 const char* UTF-8 编码的字节串,而不是 PyObject*

传给该函数的不同属性名称应当保持在较少的数量,通常是通过使用静态分配的字符串作为 attr_name 来做到这一点。对于编译时未知的属性名称,建议直接调用 PyUnicode_FromString()PyObject_DelAttr()。更多相关细节,请参阅 PyUnicode_InternFromString(),它可在内部用于创建供查找的键对象。

PyObject *PyObject_GenericGetDict(PyObject *o, void *context)
返回值:新的引用。 属于 稳定 ABI 自 3.10 版起.

__dict__ 描述符的获取函数的一种通用实现。必要时会创建该字典。

此函数还可能会被调用以获取对象 o__dict__。当调用它时可传入 NULL 作为 context。由于此函数可能需要为字典分配内存,所以在访问对象上的属性时调用 PyObject_GetAttr() 可能会更为高效。

当失败时,将返回 NULL 并设置一个异常。

Added in version 3.3.

int PyObject_GenericSetDict(PyObject *o, PyObject *value, void *context)
属于 稳定 ABI 自 3.7 版起.

__dict__ 描述符设置函数的一种通用实现。这里不允许删除该字典。

Added in version 3.3.

PyObject **_PyObject_GetDictPtr(PyObject *obj)

返回一个指向对象 obj__dict__ 的指针。如果不存在 __dict__,则返回 NULL 并且不设置异常。

此函数可能需要为字典分配内存,所以在访问对象上的属性时调用 PyObject_GetAttr() 可能会更为高效。

PyObject *PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)
返回值:新的引用。 属于 稳定 ABI.

使用由 opid 指定的操作来比较 o1o2 的值,操作必须为 Py_LT, Py_LE, Py_EQ, Py_NE, Py_GTPy_GE 中的一个,分别对应于 <, <=, ==, !=, >>=。这等价于 Python 表达式 o1 op o2,其中 op 是与 opid 对应的运算符。成功时返回比较结果值,失败时返回 NULL

int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)
属于 稳定 ABI.

PyObject_RichCompare() 类似,使用 opid 所指定的操作来比较 o1o2 的值,但在出错时返回 -1,在结果为假值时返回 0,在其他情况下返回 1

备注

如果 o1o2 是同一个对象,PyObject_RichCompareBool() 将总是为 Py_EQ 返回 1 并为 Py_NE 返回 0

PyObject *PyObject_Format(PyObject *obj, PyObject *format_spec)
属于 稳定 ABI.

使用 format_spec 格式化 obj。这等价于 Python 表达式 format(obj, format_spec)

format_spec 可以为 NULL。在此情况下调用将等价于 format(obj)。成功时返回已格式化的字符串,失败时返回 NULL.

PyObject *PyObject_Repr(PyObject *o)
返回值:新的引用。 属于 稳定 ABI.

计算对象 o 的字符串形式。成功时返回字符串,失败时返回 NULL。这相当于 Python 表达式 repr(o)。由内置函数 repr() 调用。

在 3.4 版本发生变更: 该函数现在包含一个调试断言,用以确保不会静默地丢弃活动的异常。

PyObject *PyObject_ASCII(PyObject *o)
返回值:新的引用。 属于 稳定 ABI.

PyObject_Repr() 一样,计算对象 o 的字符串形式,但在 PyObject_Repr() 返回的字符串中用 \x\u\U 转义非 ASCII 字符。这将生成一个类似于 Python 2 中由 PyObject_Repr() 返回的字符串。由内置函数 ascii() 调用。

PyObject *PyObject_Str(PyObject *o)
返回值:新的引用。 属于 稳定 ABI.

计算对象 o 的字符串形式。成功时返回字符串,失败时返回 NULL。这相当于 Python 表达式 str(o)。由内置函数 str() 调用,因此也由 print() 函数调用。

在 3.4 版本发生变更: 该函数现在包含一个调试断言,用以确保不会静默地丢弃活动的异常。

PyObject *PyObject_Bytes(PyObject *o)
返回值:新的引用。 属于 稳定 ABI.

计算对象 o 的字节形式。失败时返回 NULL,成功时返回一个字节串对象。当 o 不是整数时,这相当于 Python 表达式 bytes(o)。与 bytes(o) 不同的是,当 o 为整数时会引发 TypeError,而不是返回一个初始为零的字节串对象。

int PyObject_IsSubclass(PyObject *derived, PyObject *cls)
属于 稳定 ABI.

如果 derived 类与 cls 类相同或为其派生类,则返回 1,否则返回 0。如果出错则返回 -1

如果 cls 是元组,则会对 cls 进行逐项检测。如果至少有一次检测返回 1,结果将为 1,否则将是 0

如果 cls 具有 __subclasscheck__() 方法,它将被调用以确定 PEP 3119 所描述的子类状态。在其他情况下,如果 derived 是一个直接或间接子类即包含在 cls.__mro__ 中则它就是 cls 的子类。

通常只有类对象,即 type 或其派生类的实例才会被视为类。但是,对象可以通过设置 __bases__ 属性(它必须是由基类组成的元组)来覆盖此定义。

int PyObject_IsInstance(PyObject *inst, PyObject *cls)
属于 稳定 ABI.

如果 instcls 类或其子类的实例,则返回 1,如果不是则返回 0。如果出错则返回 -1 并设置一个异常。

如果 cls 是元组,则会对 cls 进行逐项检测。如果至少有一次检测返回 1,结果将为 1,否则将是 0

如果 cls 具有 __instancecheck__() 方法,它将被调用以确定 PEP 3119 所描述的子类状态。在其他情况下,如果 inst 的类是 cls 的子类则它就是 cls 的实例。

实例 inst 可以通过设置 __class__ 属性来覆盖它是否会被视为类。

对象 cls 可以通过设置 __bases__ 属性(它必须是由基类组成的元组)来覆盖它是否会被视为类,及其有哪些基类。

Py_hash_t PyObject_Hash(PyObject *o)
属于 稳定 ABI.

计算并返回对象 o 的哈希值。失败时返回 -1。这相当于 Python 表达式 hash(o)

在 3.2 版本发生变更: 现在的返回类型是 Py_hash_t。这是一个大小与 Py_ssize_t 相同的有符号整数。

Py_hash_t PyObject_HashNotImplemented(PyObject *o)
属于 稳定 ABI.

设置一个 TypeError 来指明 type(o) 不是 hashable 并返回 -1。此函数在存储于 tp_hash 槽位内时会获得特别对待,允许某个类型显式地向解释器指明它是不可哈希对象。

int PyObject_IsTrue(PyObject *o)
属于 稳定 ABI.

如果对象 o 被认为是 true,则返回 1,否则返回 0。这相当于 Python 表达式 not not o。失败则返回 -1

int PyObject_Not(PyObject *o)
属于 稳定 ABI.

如果对象 o 被认为是 true,则返回 0,否则返回 1。这相当于 Python 表达式 not o。失败则返回 -1

PyObject *PyObject_Type(PyObject *o)
返回值:新的引用。 属于 稳定 ABI.

o 不为 NULL 时,返回一个与对象 o 的类型相对应的类型对象。当失败时,将引发 SystemError 并返回 NULL。这等同于 Python 表达式 type(o)。该函数会新建一个指向返回值的 strong reference。实际上没有多少理由使用此函数来替代 Py_TYPE() 函数,后者将返回一个 PyTypeObject* 类型的指针,除非是需要一个新的 strong reference

int PyObject_TypeCheck(PyObject *o, PyTypeObject *type)

如果对象 otype 类型或其子类型,则返回非零,否则返回 0。两个参数都必须非 NULL

Py_ssize_t PyObject_Size(PyObject *o)
Py_ssize_t PyObject_Length(PyObject *o)
属于 稳定 ABI.

返回对象 o 的长度。如果对象 o 支持序列和映射协议,则返回序列长度。出错时返回 -1。这等同于 Python 表达式 len(o).

Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)

返回对象 o 的估计长度。首先尝试返回实际长度,然后用 __length_hint__() 进行估计,最后返回默认值。出错时返回 -1。这等同于 Python 表达式 operator.length_hint(o, defaultvalue).

Added in version 3.4.

PyObject *PyObject_GetItem(PyObject *o, PyObject *key)
返回值:新的引用。 属于 稳定 ABI.

返回对象 key 对应的 o 元素,或在失败时返回 NULL。这等同于 Python 表达式 o[key]

int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)
属于 稳定 ABI.

将对象 key 映射到值 v。失败时引发异常并返回 -1;成功时返回 0。这相当于 Python 语句 o[key] = v。该函数 不会 偷取 v 的引用计数。

int PyObject_DelItem(PyObject *o, PyObject *key)
属于 稳定 ABI.

从对象 o 中移除对象 key 的映射。失败时返回 -1。这相当于 Python 语句 del o[key]

int PyObject_DelItemString(PyObject *o, const char *key)
属于 稳定 ABI.

这与 PyObject_DelItem() 相同,但 key 被指定为 const char* UTF-8 编码的字节串,而不是 PyObject*

PyObject *PyObject_Dir(PyObject *o)
返回值:新的引用。 属于 稳定 ABI.

相当于 Python 表达式 dir(o),返回一个(可能为空)适合对象参数的字符串列表,如果出错则返回 NULL。如果参数为 NULL,类似 Python 的 dir(),则返回当前 locals 的名字;这时如果没有活动的执行框架,则返回 NULL,但 PyErr_Occurred() 将返回 false。

PyObject *PyObject_GetIter(PyObject *o)
返回值:新的引用。 属于 稳定 ABI.

等同于 Python 表达式 iter(o)。为对象参数返回一个新的迭代器,如果该对象已经是一个迭代器,则返回对象本身。如果对象不能被迭代,会引发 TypeError,并返回 NULL

PyObject *PyObject_SelfIter(PyObject *obj)
返回值:新的引用。 属于 稳定 ABI.

这等价于 Python __iter__(self): return self 方法。它是针对 iterator 类型设计的,将在 PyTypeObject.tp_iter 槽位中使用。

PyObject *PyObject_GetAIter(PyObject *o)
返回值:新的引用。 属于 稳定 ABI 自 3.10 版起.

等同于 Python 表达式 aiter(o)。接受一个 AsyncIterable 对象,并为其返回一个 AsyncIterator。通常返回的是一个新迭代器,但如果参数是一个 AsyncIterator,将返回其自身。如果该对象不能被迭代,会引发 TypeError,并返回 NULL

Added in version 3.10.

void *PyObject_GetTypeData(PyObject *o, PyTypeObject *cls)
属于 稳定 ABI 自 3.12 版起.

获取一个指向为 cls 保留的子类专属数据的指针。

对象 o 必须为 cls 的实例,而 cls 必须使用负的 PyType_Spec.basicsize 来创建。Python 不会检查这一点。

发生错误时,将设置异常并返回 NULL

Added in version 3.12.

Py_ssize_t PyType_GetTypeDataSize(PyTypeObject *cls)
属于 稳定 ABI 自 3.12 版起.

返回为 cls 保留的实例内存空间大小,即 PyObject_GetTypeData() 所返回的内存大小。

这可能会大于使用 -PyType_Spec.basicsize 请求到的大小;可以安全地使用这个更大的值 (例如通过 memset())。

类型 cls 必须 使用负的 PyType_Spec.basicsize 来创建。Python 不会检查这一点。

当失败时,将设置异常并返回一个负值。

Added in version 3.12.

void *PyObject_GetItemData(PyObject *o)

使用 Py_TPFLAGS_ITEMS_AT_END 获取一个指向类的单独条目数据的指针。

出错时,将设置异常并返回 NULL。如果 o 没有设置 Py_TPFLAGS_ITEMS_AT_END 则会引发 TypeError.

Added in version 3.12.

int PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg)

访问被管理的 obj 的字典。

此函数必须只在设置了 Py_TPFLAGS_MANAGED_DICT 旗标的类型的遍历函数中被调用。

Added in version 3.13.

void PyObject_ClearManagedDict(PyObject *obj)

清空被管理的 obj 的字典。

此函数必须只在设置了 Py_TPFLAGS_MANAGED_DICT 旗标的类型的清理函数中被调用。

Added in version 3.13.

int PyUnstable_Object_EnableDeferredRefcount(PyObject *obj)
这是 不稳定 API。它可能在次要版本中不经警告地被更改。

obj 上启用 推迟引用计数,如果运行时支持的话。在 自由线程 构建版中,这将允许解释器避免对 obj 的引用计数调整,这可以提升多线程性能。其权衡之处在于,obj 对象仅会在追踪式垃圾回收器运行时被释放,而不会在解释器不再持有该对象的任何引用时立即释放。

如果 obj 上启用了延迟引用计数,此函数返回 1;若延迟引用计数不被支持,或解释器忽略了该提示(例如 obj 上已启用延迟引用计数),则返回 0。该函数是线程安全的,且不会执行失败。

此函数在启用了 GIL 的构建版上将不做任何事,因为该版本不支持推迟引用计数。如果 obj 未被垃圾回收器追踪则此函数也不会做任何事 (参见 gc.is_tracked()PyObject_GC_IsTracked())。

此函数应当在 obj 被创建之后立即供创建它的代码使用,就如在对象 tp_new 的槽位中那样。

Added in version 3.14.

int PyUnstable_Object_IsUniqueReferencedTemporary(PyObject *obj)
这是 不稳定 API。它可能在次要版本中不经警告地被更改。

检测 obj 是否是一个单独临时对象。如果确定 obj 是一个单独临时对象则返回 1,否则返回 0。此函数一定不会执行失败,但该检测是偏保守的,在某些情况下即使 obj 是一个单独临时对象也可能返回 0

如果一个对象是唯一的临时对象,则可以保证当前代码对该对象有唯一的引用。对于 C 函数的参数,应该这样做,而不是检查引用计数是否为 1。从 Python 3.14 开始,解释器在将对象加载到操作数堆栈时,通过在可能的情况下 借用 引用,在内部避免了一些引用计数修改,这意味着引用计数 1 本身并不能保证函数参数被唯一引用。

在下面的例子中,调用 my_func 时使用一个唯一的临时对象作为参数:

my_func([1, 2, 3])

在下面的例子中,调用 my_func不是 使用一个唯一的临时对象作为参数,即使它的引用计数为 1:

my_list = [1, 2, 3]
my_func(my_list)

另请参阅 Py_REFCNT() 函数。

Added in version 3.14.

int PyUnstable_IsImmortal(PyObject *obj)
这是 不稳定 API。它可能在次要版本中不经警告地被更改。

如果 objimmortal,这个函数返回非零,否则返回零。这个函数不会失败。

备注

在一个 CPython 版本中是不朽的对象不能保证在另一个 CPython 版本中还是不朽的。

Added in version 3.14.

int PyUnstable_TryIncRef(PyObject *obj)
这是 不稳定 API。它可能在次要版本中不经警告地被更改。

如果 obj 的引用计数不为零,则增加引用计数。如果对象的引用计数已成功递增,则返回 1。否则,此函数返回 0

PyUnstable_EnableTryIncRef() 必须先前在 obj 上被调用否则此函数可能在 free-threaded build 中错误地返回 0

此函数在逻辑上相当于以下 C 代码,区别在于它在 free-threaded build 中的行为是原子化的:

if (Py_REFCNT(op) > 0) {
   Py_INCREF(op);
   return 1;
}
return 0;

这旨在作为一个构建块,用于管理弱引用,而不会产生 Python 弱引用对象 的开销。

通常,正确使用此函数需要 obj 的释放器 (tp_dealloc) 的支持。例如,下面的草图可以用来实现一个“weakmap”,就像一个特定类型的 WeakValueDictionary 一样:

PyMutex mutex;

PyObject *
add_entry(weakmap_key_type *key, PyObject *value)
{
    PyUnstable_EnableTryIncRef(value);
    weakmap_type weakmap = ...;
    PyMutex_Lock(&mutex);
    weakmap_add_entry(weakmap, key, value);
    PyMutex_Unlock(&mutex);
    Py_RETURN_NONE;
}

PyObject *
get_value(weakmap_key_type *key)
{
    weakmap_type weakmap = ...;
    PyMutex_Lock(&mutex);
    PyObject *result = weakmap_find(weakmap, key);
    if (PyUnstable_TryIncRef(result)) {
        // `result` 可以安全使用
        PyMutex_Unlock(&mutex);
        return result;
    }
    // 如果我们到这里,`result` 开始被垃圾回收,
    // 但还没有从弱映射中移除
    PyMutex_Unlock(&mutex);
    return NULL;
}

// weakmap 值的 tp_dealloc 函数
void
value_dealloc(PyObject *value)
{
    weakmap_type weakmap = ...;
    PyMutex_Lock(&mutex);
    weakmap_remove_value(weakmap, value);

    ...
    PyMutex_Unlock(&mutex);
}

Added in version 3.14.

void PyUnstable_EnableTryIncRef(PyObject *obj)
这是 不稳定 API。它可能在次要版本中不经警告地被更改。

允许在 obj 上后续使用 PyUnstable_TryIncRef()。调用者在调用时必须持有 objstrong reference.

Added in version 3.14.

int PyUnstable_Object_IsUniquelyReferenced(PyObject *op)
这是 不稳定 API。它可能在次要版本中不经警告地被更改。

确定 op 是否只有一个引用。

在启用 GIL 的构建中,此函数等价于 Py_REFCNT(op) == 1

free-threaded build 中,这将检查 opreference count 是否等于一同时额外检查 op 是否仅由该线程使用。 Py_REFCNT(op) == 1 在自由线程构建版中 不是 线程安全的;应当优先使用此函数。

调用者必须持有一个 attached thread state,尽管这个函数不调用 Python 解释器。这个函数不会失败。

Added in version 3.14.

int PyUnstable_SetImmortal(PyObject *op)
这是 不稳定 API。它可能在次要版本中不经警告地被更改。

Marks the object op immortal. The argument should be uniquely referenced by the calling thread. This is intended to be used for reducing reference counting contention in the free-threaded build for objects which are shared across threads.

This is a one-way process: objects can only be made immortal; they cannot be made mortal once again. Immortal objects do not participate in reference counting and will never be garbage collected. If the object is GC-tracked, it is untracked.

This function is intended to be used soon after op is created, by the code that creates it, such as in the object's tp_new slot. Returns 1 if the object was made immortal and returns 0 if it was not. This function cannot fail.

Added in version 3.15.0a6 (unreleased).