类型对象

type PyTypeObject
属于 稳定 ABI (作为不透明的结构体).

用于描述内置类型的对象的 C 结构。

PyTypeObject PyType_Type
属于 稳定 ABI.

这是类型对象的类型对象;它与 Python 层面的 type 是相同的对象。

int PyType_Check(PyObject *o)

如果对象 o 是一个类型对象,包括派生自标准类型对象的类型实例则返回非零值。在所有其它情况下都返回 0。此函数将总是成功执行。

int PyType_CheckExact(PyObject *o)

如果对象 o 是一个类型对象,但不是标准类型对象的子类型则返回非零值。在所有其它情况下都返回 0。此函数将总是成功执行。

unsigned int PyType_ClearCache()
属于 稳定 ABI.

清空内部查找缓存。返回当前版本标签。

unsigned long PyType_GetFlags(PyTypeObject *type)
属于 稳定 ABI.

返回 type 的 tp_flags 成员。此函数主要是配合 Py_LIMITED_API 使用;单独的旗标位会确保在各个 Python 发布版之间保持稳定,但对 tp_flags 本身的访问并不是 受限 API 的一部分。

在 3.2 版本加入.

在 3.4 版本发生变更: 返回类型现在是 unsigned long 而不是 long。

PyObject *PyType_GetDict(PyTypeObject *type)

返回类型对象的内部命名空间,它在其他情况下只能通过只读代理 (cls.__dict__) 对外公开。 这可以代替直接访问 tp_dict。返回的字典必须视为是只读的。

该函数用于特定的嵌入和语言绑定场景,在这些场景下需要直接访问该字典而间接访问(例如通过代理或 PyObject_GetAttr() 访问)并不足够。

扩展模块在设置它们自己的类型时应当继续直接或间接地使用 tp_dict。

在 3.12 版本加入.

void PyType_Modified(PyTypeObject *type)
属于 稳定 ABI.

使该类型及其所有子类型的内部查找缓存失效。此函数必须在对该类型的属性或基类进行任何手动修改之后调用。

int PyType_AddWatcher(PyType_WatchCallback callback)

注册 callback 作为类型监视器。返回一个非负的整数 ID,它必须传给将来对 PyType_Watch() 的调用。如果出错(例如没有足够的可用监视器 ID),则返回 -1 并设置一个异常。

在自由线程构建版中,PyType_AddWatcher() 不是线程安全的,因此它必须在启动时调用(在产生第一个线程之前)。

在 3.12 版本加入.

int PyType_ClearWatcher(int watcher_id)

清除由 watcher_id (之前从 PyType_AddWatcher() 返回) 所标识的 watcher。成功时返回 0,出错时(例如 watcher_id 未被注册)返回 -1。

扩展在调用 PyType_ClearWatcher 时绝不能使用不是之前调用 PyType_AddWatcher() 所返回的 watcher_id.

在 3.12 版本加入.

int PyType_Watch(int watcher_id, PyObject *type)

将 type 标记为已监视。每当 PyType_Modified() 报告 type 发生变化时,由 PyType_AddWatcher() 授予 watcher_id 的回调将被调用。 (如果在 type 的一系列连续修改之间没有调用 _PyType_Lookup(),则回调可能只被调用一次;这是一个实现细节并可能发生变化)。

该回调还会在释放所监视的堆类型时被唤起。

扩展在调用 PyType_Watch 时绝不能使用不是之前调用 PyType_AddWatcher() 所返回的 watcher_id.

在 3.12 版本加入.

在 3.15 版本发生变更: 现在该回调还会在释放所监视的堆类型时被唤起。

int PyType_Unwatch(int watcher_id, PyObject *type)

将 type 标记为未被监视。这将撤销之前对 PyType_Watch() 调用的效果。type 必须不为 NULL.

扩展在调用此函数时传入的 watcher_id 绝不能不是之前调用 PyType_AddWatcher() 所返回的值。

成功时,此函数将返回 0。失败时,此函数将返回 -1 并设置一个异常。

在 3.12 版本加入.

typedef int (*PyType_WatchCallback)(PyObject *type)

类型监视器回调函数的类型。

回调不可以修改 type 或是导致 PyType_Modified() 在 type 或其 MRO 中的任何类型上被调用;违反此规则可能导致无限递归。

该回调可能在类型释放期间被调用。 在此情况下,类型对象会临时复活(其引用计数至少为 1)并且其属性仍然可用。 不过,回调不应保存新的对该类型的强引用,因为这会使对象重新存活并阻止其被释放。

在 3.12 版本加入.

在 3.15 版本发生变更: 现在该回调可能会在释放所监视的堆类型期间被调用。

int PyType_HasFeature(PyTypeObject *o, int feature)

如果类型对象 o 设置了特性 feature 则返回非零值。类型特性是用单个比特位旗标来表示的。

int PyType_FastSubclass(PyTypeObject *type, int flag)

如果类型对象 type 设置了子类旗标 flag 则返回非零值。子类旗标是由 Py_TPFLAGS_*_SUBCLASS 表示的。此函数将被许多针对常见类型的 _Check 函数所使用。

参见

PyObject_TypeCheck(),该函数被用作针对不带子类旗标的类型的 _Check 函数的较慢速的替代物。

int PyType_IS_GC(PyTypeObject *o)

如果类型对象包括了对循环检测器的支持则返回真值;这将测试类型旗标 Py_TPFLAGS_HAVE_GC。

int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
属于 稳定 ABI.

如果 a 是 b 的子类型则返回真值。

此函数只检查实际的子类型,这意味着 __subclasscheck__() 不会在 b 上被调用。请调用 PyObject_IsSubclass() 来执行与 issubclass() 所做的相同检查。

PyObject *PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
返回值:新的引用。 属于 稳定 ABI.

类型对象的 tp_alloc 槽位的通用处理器。使用 Python 的默认内存分配机制为新建的实例分配内存,向内存写入零值,然后初始化内存就如同调用了 PyObject_Init() 或 PyObject_InitVar() 一样。

请不要直接调用此函数为对象分配内存;而应调用类型的 tp_alloc 槽位。

对于支持垃圾回收的类型(即设置了 Py_TPFLAGS_HAVE_GC 旗标),此函数的行为类似于 PyObject_GC_New 或 PyObject_GC_NewVar (不同之处在于内存在初始化之前会确保被写入零值),并且应当与 tp_free 中的 PyObject_GC_Del() 相对应。在其他情况下,其行为像是 PyObject_New 或 PyObject_NewVar (不同之处在于内存在初始化之前会确保被写入零值) 并且应当与 tp_free 中的 PyObject_Free() 相对应。

PyObject *PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
返回值:新的引用。 属于 稳定 ABI.

类型对象的 tp_new 槽位的通用处理器。使用类型的 tp_alloc 槽位创建一个新的实例并返回结果对象。

int PyType_Ready(PyTypeObject *type)
属于 稳定 ABI.

最终化一个类型对象。这应当在所有类型对象上调用以完成它们的初始化。此函数会负责从一个类型的基类添加被继承的槽位。成功时返回 0,或是在出错时返回 -1 并设置一个异常。

备注

如果某些基类实现了 GC 协议并且所提供的类型的旗标中未包括 Py_TPFLAGS_HAVE_GC,则将自动从其父类实现 GC 协议。相反地,如果被创建的类型的旗标中确实包含 Py_TPFLAGS_HAVE_GC 则它 必须 自己实现 GC 协议,至少要实现 tp_traverse 句柄。

PyObject *PyType_GetName(PyTypeObject *type)
返回值:新的引用。 属于 稳定 ABI 自 3.11 版起.

返回类型名称。等同于获取类型的 __name__ 属性。

在 3.11 版本加入.

PyObject *PyType_GetQualName(PyTypeObject *type)
返回值:新的引用。 属于 稳定 ABI 自 3.11 版起.

返回类型的限定名称。等同于获取类型的 __qualname__ 属性。

在 3.11 版本加入.

PyObject *PyType_GetFullyQualifiedName(PyTypeObject *type)
属于 稳定 ABI 自 3.13 版起.

返回类型的完整限定名称。等同于 f"{type.__module__}.{type.__qualname__}",或者如果 type.__module__ 不是字符串或是等于 "builtins" 则等同于 type.__qualname__.

在 3.13 版本加入.

PyObject *PyType_GetModuleName(PyTypeObject *type)
属于 稳定 ABI 自 3.13 版起.

返回类型的模块名称。等价于获取 type.__module__ 属性。

在 3.13 版本加入.

void *PyType_GetSlot(PyTypeObject *type, int slot)
属于 稳定 ABI 自 3.4 版起.

返回存储在给定槽位中的函数指针。如果结果为 NULL,则表示或者该槽位为 NULL,或者该函数调用传入了无效的形参。 调用方通常要将结果指针转换到适当的函数类型。

请参阅 PyType_Slot.slot 查看可用的 slot 参数值。

在 3.4 版本加入.

在 3.10 版本发生变更: PyType_GetSlot() 现在可以接受所有类型。在此之前,它被限制为 堆类型。

PyObject *PyType_GetModule(PyTypeObject *type)
返回值:借入的引用。 属于 稳定 ABI 自 3.10 版起.

返回当使用 PyType_FromModuleAndSpec() 创建类型时关联到给定类型的模块对象。

返回的引用是从 type 借入的,并且只要你还持有对 type 的引用就会保持有效。 请不要通过 Py_DECREF() 或类似函数来释放它。

如果没有关联到给定类型的模块,则设置 TypeError 并返回 NULL。

此函数通常被用于获取方法定义所在的模块。请注意在这样的方法中,PyType_GetModule(Py_TYPE(self)) 可能不会返回预期的结果。 Py_TYPE(self) 可以是目标类的一个 子类,而子类并不一定是在与其超类相同的模块中定义的。 请参阅 PyCMethod 了解如何获取方法定义所在的类。 请参阅 PyType_GetModuleByToken() 了解有关无法使用 PyCMethod 的情况。

在 3.9 版本加入.

void *PyType_GetModuleState(PyTypeObject *type)
属于 稳定 ABI 自 3.10 版起.

返回关联到给定类型的模块对象的状态。这是一个在 PyType_GetModule() 的结果上调用 PyModule_GetState() 的快捷方式。

如果没有关联到给定类型的模块,则设置 TypeError 并返回 NULL。

如果 type 有关联的模块但其状态为 NULL,则返回 NULL 且不设置异常。

在 3.9 版本加入.

PyObject *PyType_GetModuleByToken(PyTypeObject *type, const void *mod_token)
返回值:新的引用。 属于 稳定 ABI 自 3.15 版起.

查找第一个其模块包含给定 module token 的超类,并返回该模块。

如果未找到模块,则会引发 TypeError 并返回 NULL。

此函数预期会与 PyModule_GetState() 一起使用以便从槽位方法 (如 tp_init 或 nb_add) 及其他定义方法的类无法使用 PyCMethod 调用惯例来传递的场合获取模块状态。

在 3.15 版本加入.

PyObject *PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def)
返回值:借入的引用。 属于 稳定 ABI 自 3.13 版起.

查找第一个其模块由给定的 PyModuleDef def 创建,或其 module token 等于 def 的超类,并返回该模块。

请注意,由 PyModuleDef 创建的模块,其令牌始终会被设置为 PyModuleDef 的地址。换言之,该函数与 PyType_GetModuleByToken() 等效,但区别在于:

  • 返回一个借用的引用,并且

  • 具有非 void* 参数类型(这在 C 语言中仅是一种外观上的差异)。

返回的引用是从 type 借入的,并且只要你还持有对 type 的引用就会保持有效。 请不要通过 Py_DECREF() 或类似函数来释放它。

在 3.11 版本加入.

int PyType_GetBaseByToken(PyTypeObject *type, void *tp_token, PyTypeObject **result)
属于 稳定 ABI 自 3.14 版起.

在 type 的 方法解析顺序 中,找到第一个其 Py_tp_token 令牌与 tp_token 相等的超类。

  • 如果找到,则将 *result 设为一个新的指向该值的 strong reference 并返回 1。

  • 如果未找到,则将 *result 设为 NULL 并返回 0。

  • 当失败时,则将 *result 设为 NULL 并返回 -1 同时设置一个异常。

result 参数可能为 NULL,在此情况下将不设置 *result。如果你只需要返回值则可以这样做。

tp_token 参数不可为 NULL。

在 3.14 版本加入.

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

尝试为给定的类型设置一个版本标签。

如果类型已有合法的版本标签或已设置了新的版本标签则返回 1,或者如果无法设置新的标签则返回 0。

在 3.12 版本加入.

int PyType_SUPPORTS_WEAKREFS(PyTypeObject *type)

如果 type 的实例支持创建弱引用则返回真值,否则返回假值。此函数总是会成功执行。type 必须不为 NULL。

创建堆分配类型

以下函数被用于创建 堆类型:

PyObject *PyType_FromSlots(const PySlot *slots)
属于 稳定 ABI 自 3.15 版起.

从 PySlot 数组中创建并返回一个 heap type。有关槽位的通用信息,请参阅 定位槽位;有关类型创建专用槽位的信息,请参阅 类型槽位 ID。

此函数会在新类型上调用 PyType_Ready()。

请注意此函数并 不 完全匹配调用 type() 或使用 class 语句的行为。 对于用户提供的类型或元类,推荐 调用 type (或元类) 而不是 PyType_From* 函数。特别地:

槽通常被定义为全局静态常量数组。然而,有时槽的值在编译时并非静态已知。例如,像 Py_tp_bases、Py_tp_metaclass 和 Py_tp_module 这样的槽需要运行时 Python 对象。在这种情况下,建议将此类槽置于栈中,并使用 Py_slot_subslots 来引用一个静态槽数组。例如:

static const PySlot my_slots[] = {
   PySlot_STATIC_DATA(Py_tp_name, "MyClass"),
   PySlot_FUNC(Py_tp_repr, my_repr_func),
   ...
   PySlot_END
};

PyObject *make_my_class(PyObject *module) {
   PySlot all_slots[] = {
      PySlot_STATIC_DATA(Py_slot_subslots, my_slots),
      PySlot_DATA(Py_tp_module, module),
      PySlot_END
   };
   return PyType_FromSlots(all_slots);
}

未使用 Py_TPFLAGS_IMMUTABLETYPE 标志创建的堆类型可能会被修改,例如通过为其设置属性;这与在 Python 代码中定义的类类似。有时,这类修改对于完整初始化类型是必要的;但您可能希望防止用户在初始化完成后更改该类型:

int PyType_Freeze(PyTypeObject *type)
属于 稳定 ABI 自 3.14 版起.

使类型不可变:设置 Py_TPFLAGS_IMMUTABLETYPE 标志。

type 的所有基类必须是不可变的。

如果成功,返回 0。如果发生错误,设置异常并返回 -1。

在使类型不可变之前,不能使用它。例如,在类型变为不可变之前,不能创建类型实例。

在 3.14 版本加入.

类型槽位 ID

大多数类型槽 ID 的命名方式与结构体字段名相同,即 PyTypeObject、PyNumberMethods、PySequenceMethods、PyMappingMethods 和 PyAsyncMethods,并在其后添加前缀 Py_。例如,可以使用:

以下槽位在指定为槽位时需要额外的考量:

不与 PyTypeObject 结构字段直接对应的附加槽位:

下列“offset”字段不可使用 PyType_Slot 来设置:

如果无法切换为 MANAGED 旗标(例如,对于 vectorcall 或是为了支持早于 3.12 版的 Python),请在 Py_tp_members 中指定 offset。详情参见 PyMemberDef 文档.

以下内部字段在创建堆类型时完全不可设置:

Py_tp_base 槽位与 Py_tp_bases 槽位等效;两者均可设置为某种类型或类型元组。若同时指定两者,则采用 Py_tp_bases 的值。

槽位值不得为 NULL,但以下情况除外:

在 3.9 版本发生变更: PyBufferProcs 中的槽位可能会在不受限 API 中被设置。

在 3.11 版本发生变更: 现在 bf_getbuffer 和 bf_releasebuffer 将在 受限 API 中可用。

在 3.14 版本发生变更: 字段 tp_vectorcall 现在可以使用 Py_tp_vectorcall 来设置。详情参见该字段的文档。

在 3.15 版本发生变更: Py_tp_bases 槽可设置为单一类型对象,从而使其与 Py_tp_base 槽等效。此前,必须使用类型元组。

以下槽位对应于底层类型结构中的字段,但若要将其用作槽位,还需额外说明:

Py_tp_name
属于 稳定 ABI 自 3.15 版起.

Slot ID 用于指定类型名称,用于设置 PyTypeObject.tp_name。

此槽(或 PyType_Spec.name)是创建类型所必需的。

此内容不得用于 PyType_Spec.slots。请改用 PyType_Spec.name。

CPython 会按顺序处理槽位。建议将 Py_tp_name 置于槽位数组的开头,这样如果后续槽位的处理失败,错误消息中就能包含该名称。

在 3.15 版本加入.

Py_tp_basicsize
属于 稳定 ABI 自 3.15 版起.

Slot ID 表示实例的大小(以字节为单位)。它用于设置 PyTypeObject.tp_basicsize。

该值必须为正数。

此内容不得用于 PyType_Spec.slots。请改用 PyType_Spec.basicsize。

此插槽不得与 PyType_GetSlot() 配合使用。如有需要,请使用 PyTypeObject.tp_basicsize;但请注意,类型的尺寸通常被视为实现细节。

在 3.15 版本加入.

Py_tp_extra_basicsize
属于 稳定 ABI 自 3.15 版起.

Slot ID 表示类型数据的大小(以字节为单位),即该类实例除了需要占用超类所需空间之外,还需要额外占用多少空间。

该值将与超类的尺寸一起用于设置 PyTypeObject.tp_basicsize。Python 将根据需要插入填充,以满足 tp_basicsize 的对齐要求。

使用 PyObject_GetTypeData() 获取一个指向以这种方式预留的类特定内存的指针。

该值必须为正数。若需指定实例无需额外空间(即空间应被继承),则应省略 Py_tp_extra_basicsize 槽,而非将其设置为零。

同时指定 Py_tp_basicsize 和 Py_tp_extra_basicsize 会引发错误。

此内容不得用于 PyType_Spec.slots。请使用负值 PyType_Spec.basicsize 代替。

此插槽不得与 PyType_GetSlot() 配合使用。

在 3.15 版本加入.

Py_tp_itemsize
属于 稳定 ABI 自 3.15 版起.

Slot ID 表示可变长度类型中一个元素的字节大小。用于设置 PyTypeObject.tp_itemsize。有关注意事项,请参阅 tp_itemsize 文档。

该值必须为正数。

如果此插槽缺失,则将继承 tp_itemsize。扩展任意变量大小类是危险的,因为某些类型使用固定偏移量来容纳变量大小内存,这可能导致其与子类所使用的固定大小内存发生重叠。为防止此类错误,只有在以下情况下才能继承 itemsize:

此槽位不可用于 PyType_Spec.slots。 请改用 PyType_Spec.itemsize。

此插槽不得与 PyType_GetSlot() 配合使用。

在 3.15 版本加入.

Py_tp_flags
属于 稳定 ABI 自 3.15 版起.

类型旗标的 Slot ID,用于设置 PyTypeObject.tp_flags。

未设置 Py_TPFLAGS_HEAPTYPE 旗标,PyType_FromSpecWithBases() 会自动设置它。

此内容不得用于 PyType_Spec.slots。请使用负值 PyType_Spec.basicsize 代替。

此插槽不得与 PyType_GetSlot() 配合使用;请改用 PyType_GetFlags()。

在 3.15 版本加入.

Py_tp_bases
属于 稳定 ABI.

Slot ID 用于基类型,用于设置 PyTypeObject.tp_bases。

该槽可设置为由类型对象组成的元组,新创建的类型应继承自该元组,就像 Python 类定义 的“位置参数”一样。

或者,也可以将该槽位设置为单个类型对象,以指定单个基类。其效果与指定单元素元组相同。

在 3.15 版本发生变更: 此前,Py_tp_bases 需要一个类型元组。

Py_tp_base
属于 稳定 ABI.

等同于 Py_tp_bases (末尾为 s)。若同时指定两者,则 Py_tp_bases 具有优先级,此插槽将被忽略。

在 3.15 版本发生变更: 此前,Py_tp_base 要求使用单一类型,而非元组。

自 3.15 版起已处于 Soft deprecated 状态: 除非需要针对较旧的 Python 版本,否则优先选用 Py_tp_bases。

以下槽位与底层结构中的公共字段并不对应:

Py_tp_metaclass
属于 稳定 ABI 自 3.15 版起.

Slot ID 用于构建所得类型对象的元类。若未指定,则元类将从基类继承而来(Py_tp_bases 或 PyType_FromMetaclass() 的 bases 参数)。

不支持重写 tp_new 的元类,除非 tp_new 为 NULL。

此内容不得用于 PyType_Spec.slots。请使用 PyType_FromMetaclass() 来指定一个带有 PyType_Spec 的元类。

此槽位不得与 PyType_GetSlot() 配合使用。请改用类型对象中的 Py_TYPE()。

在 3.15 版本加入.

Py_tp_module
属于 稳定 ABI 自 3.15 版起.

Slot ID 用于记录定义新类的模块。

该值必须是一个模块对象。该模块与新的类型相关联,之后可通过 PyType_GetModule() 获取。关联的模块不会由子类继承;必须为每个类单独指定。

此内容不得用于 PyType_Spec.slots。请使用 PyType_FromMetaclass() 来指定包含 PyType_Spec 的模块。

此插槽不得与 PyType_GetSlot() 配合使用;请改用 PyType_GetModule()。

在 3.15 版本加入.

Py_tp_token
属于 稳定 ABI 自 3.14 版起.

Slot ID 用于为某个类记录静态内存布局 ID。

如果类是通过 PyType_Spec 定义的,且该规范采用静态分配,则可以使用特殊值 Py_TP_USE_SPEC 将令牌设置为该规范:

static PyType_Slot foo_slots[] = {
   {Py_tp_token, Py_TP_USE_SPEC},

它也可以设置为任意指针,但必须确保:

  • 指针的寿命比类长,所以当类存在时,指针不能用于其他用途。

  • 它“属于”类所在的扩展模块,因此它不会与其他扩展冲突。

使用 PyType_GetBaseByToken() 来检查类的超类是否有给定的记号 —— 也就是说,检查内存布局是否兼容。

要获取给定类的记号(不考虑超类),使用 PyType_GetSlot() 和 Py_tp_token。

在 3.14 版本加入.

Py_TP_USE_SPEC
属于 稳定 ABI 自 3.14 版起.

作为与 Py_tp_token 一起使用的值,可将令牌设置为该类的 PyType_Spec。仅可用于通过 PyType_Spec 定义的类。

扩展至 NULL。

在 3.14 版本加入.

Py_tp_slots
属于 稳定 ABI 自 3.15 版起.

Slot ID 的工作方式与 Py_slot_subslots 相同,不同之处在于它指定了一个由 PyType_Slot 结构体组成的数组。

在 3.15 版本加入.

已被软弃用的 API

以下函数为 软弃用。它们将继续正常运行,但新功能将以 PyType_FromSlots() 的槽位形式添加,而非作为新 PyType_From* 函数的参数。

PyObject *PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases)
属于 稳定 ABI 自 3.12 版起.

根据 spec (参见 Py_TPFLAGS_HEAPTYPE) 创建并返回一个 堆类型.

非 NULL metaclass 参数对应于 Py_tp_metaclass 槽位。

非 NULL bases 参数对应于 Py_tp_bases 槽位,其优先级高于 Py_tp_base 和 Py_tp_bases 槽位。

非 NULL module 参数对应于 Py_tp_module 槽位。

此函数会在新类型上调用 PyType_Ready()。

请注意,此函数*并不完全等同于*调用 type() 或使用 class 语句时的行为。详情请参阅 PyType_FromSlots() 文档中的说明。

在 3.12 版本加入.

自 3.15 版起已处于 Soft deprecated 状态: 在新代码中优先选用 PyType_FromSlots()。

PyObject *PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
返回值:新的引用。 属于 稳定 ABI 自 3.10 版起.

等价于 PyType_FromMetaclass(NULL, module, spec, bases)。

在 3.9 版本加入.

在 3.10 版本发生变更: 此函数现在接受一个单独类作为 bases 参数并接受 NULL 作为 tp_doc 槽位。

在 3.12 版本发生变更: 该函数现在可以找到并使用与所提供的基类相对应的元类。在此之前,只会返回 type 实例。

元类的 tp_new 将被 忽略,这可能导致不完整的初始化。创建其元类重写 tp_new 的类的做法已被弃用。

在 3.14 版本发生变更: 不再允许创建元类重写 tp_new 的类。

自 3.15 版起已处于 Soft deprecated 状态: 在新代码中优先选用 PyType_FromSlots()。

PyObject *PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
返回值:新的引用。 属于 稳定 ABI 自 3.3 版起.

等价于 PyType_FromMetaclass(NULL, NULL, spec, bases)。

在 3.3 版本加入.

在 3.12 版本发生变更: 该函数现在可以找到并使用与所提供的基类相对应的元类。在此之前,只会返回 type 实例。

元类的 tp_new 将被 忽略,这可能导致不完整的初始化。创建其元类重写 tp_new 的类的做法已被弃用。

在 3.14 版本发生变更: 不再允许创建元类重写 tp_new 的类。

自 3.15 版起已处于 Soft deprecated 状态: 在新代码中优先选用 PyType_FromSlots()。

PyObject *PyType_FromSpec(PyType_Spec *spec)
返回值:新的引用。 属于 稳定 ABI.

等价于 PyType_FromMetaclass(NULL, NULL, spec, NULL)。

在 3.12 版本发生变更: 该函数现在可以找到并使用与 Py_tp_base[s] 槽位中提供的基类相对应的元类。在此之前,只会返回 type 实例。

元类的 tp_new 将被 忽略,这可能导致不完整的初始化。创建其元类重写 tp_new 的类的做法已被弃用。

在 3.14 版本发生变更: 不再允许创建元类重写 tp_new 的类。

自 3.15 版起已处于 Soft deprecated 状态: 在新代码中优先选用 PyType_FromSlots()。

type PyType_Spec
属于 稳定 ABI (包括所有成员).

用于定义类型行为的结构,适用于像 PyType_FromMetaclass() 这样的软弃用函数。

该结构包含多个成员,这些成员也可以指定为 slots,以对应于 PyType_FromSlots();此外还包含一个槽位条目数组,其结构更为简单。

const char *name

对应于 Py_tp_name。

int basicsize

若为正数,则对应于 Py_tp_basicsize。

若结果为负,则表示 Py_tp_extra_basicsize 被设置为其绝对值。

在 3.12 版本发生变更: 在之前版本中,此字段不能为负数。

int itemsize

对应于 Py_tp_itemsize。

unsigned int flags

对应于 Py_tp_flags。

PyType_Slot *slots

PyType_Slot (非 PySlot)结构数组。

由特殊槽位值 {0, NULL} 终止。每个槽位 ID 最多只能指定一次。

type PyType_Slot
属于 稳定 ABI (包括所有成员).

用于定义类型可选功能的结构,适用于如 PyType_FromMetaclass() 等软弃用函数。

请注意,可以使用 Py_tp_slots 将 PyType_Slot 数组包含在 PySlot 数组中;反之,也可以使用 Py_slot_subslots 实现这一操作。

每个 PyType_Slot 结构 tpslot 被解释为以下 PySlot 结构:

(PySlot){
   .sl_id=tpslot.slot,
   .sl_flags=PySlot_INTPTR | sub_static,
   .sl_ptr=tpslot.pfunc
}

其中,若该插槽需要该标志(例如对于 Py_tp_methods),则 sub_static 为 PySlot_STATIC;或者,若该标志存在于“父”插槽 Py_tp_slots 中(如有),则同样如此。

int slot

对应于 PySlot.sl_id。

void *pfunc

对应于 PySlot.sl_ptr。