# 类型对象

type PyTypeObject
  属于 受限 API （作为不透明的结构体）.

  用于描述内置类型的对象的 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 的一部分。

  Added in version 3.2.

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

PyObject *PyType_GetDict(PyTypeObject *type)

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

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

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

  Added in version 3.12.

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

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

int PyType_AddWatcher(PyType_WatchCallback callback)

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

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

  Added in version 3.12.

int PyType_ClearWatcher(int watcher_id)

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

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

  Added in version 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.

  Added in version 3.12.

int PyType_Unwatch(int watcher_id, PyObject *type)

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

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

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

  Added in version 3.12.

typedef int (*PyType_WatchCallback)(PyObject *type)

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

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

  Added in version 3.12.

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__` 属性。

  Added in version 3.11.

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

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

  Added in version 3.11.

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

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

  Added in version 3.13.

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

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

  Added in version 3.13.

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

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

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

  Added in version 3.4.

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

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

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

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

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

  This function is usually used to get the module in which a method is defined. Note that in such a method, `PyType_GetModule(Py_TYPE(self))` may not return the intended result. `Py_TYPE(self)` may be a subclass of the intended class, and subclasses are not necessarily defined in the same module as their superclass. See `PyCMethod` to get the class that defines the method. See `PyType_GetModuleByDef()` for cases when `PyCMethod` cannot be used.

  Added in version 3.9.

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

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

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

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

  Added in version 3.9.

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

  Find the first superclass whose module was created from the given `PyModuleDef` def, and return that module.

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

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

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

  Added in version 3.11.

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

  Find the first superclass in type's method resolution order whose `Py_tp_token` token is equal to the given one.

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

  - 如果未找到，则将 *result 设为 `NULL` 并返回 `0`。

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

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

  The token argument may not be `NULL`.

  Added in version 3.14.

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

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

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

  Added in version 3.12.

int PyType_SUPPORTS_WEAKREFS(PyTypeObject *type)

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

  参见

  - 弱引用对象

  - `weakref`

## 创建堆分配类型

The following functions and structs are used to create heap types.

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

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

  The metaclass metaclass is used to construct the resulting type object. When metaclass is `NULL`, the metaclass is derived from bases (or Py_tp_base[s] slots if bases is `NULL`, see below).

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

  The bases argument can be used to specify base classes; it can either be only one class or a tuple of classes. If bases is `NULL`, the `Py_tp_bases` slot is used instead. If that also is `NULL`, the `Py_tp_base` slot is used instead. If that also is `NULL`, the new type derives from `object`.

  The module argument can be used to record the module in which the new class is defined. It must be a module object or `NULL`. If not `NULL`, the module is associated with the new type and can later be retrieved with `PyType_GetModule()`. The associated module is not inherited by subclasses; it must be specified for each class individually.

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

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

  - `__new__()` 不会在新类上被调用 (它必须被设为 `type.__new__`)。

  - `__init__()` 不会在新类上被调用。

  - `__init_subclass__()` 不会在任何基类上调用。

  - `__set_name__()` 不会在新的描述器上调用。

  Added in version 3.12.

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

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

  Added in version 3.9.

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

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

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

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

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

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

  Added in version 3.3.

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

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

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

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` 的类。

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

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

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

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

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

  Added in version 3.14.

type PyType_Spec
  属于 稳定 ABI （包括所有成员）.

  Structure defining a type's behavior.

  const char *name

    Name of the type, used to set `PyTypeObject.tp_name`.

  int basicsize

    If positive, specifies the size of the instance in bytes. It is used to set `PyTypeObject.tp_basicsize`.

    If zero, specifies that `tp_basicsize` should be inherited.

    If negative, the absolute value specifies how much space instances of the class need in addition to the superclass. Use `PyObject_GetTypeData()` to get a pointer to subclass-specific memory reserved this way. For negative `basicsize`, Python will insert padding when needed to meet `tp_basicsize`'s alignment requirements.

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

  int itemsize

    Size of one element of a variable-size type, in bytes. Used to set `PyTypeObject.tp_itemsize`. See `tp_itemsize` documentation for caveats.

    If zero, `tp_itemsize` is inherited. Extending arbitrary variable-sized classes is dangerous, since some types use a fixed offset for variable-sized memory, which can then overlap fixed-sized memory used by a subclass. To help prevent mistakes, inheriting `itemsize` is only possible in the following situations:

    - 基类不是可变大小的 (即其 `tp_itemsize`)。

    - 所请求的 `PyType_Spec.basicsize` 为正值，表明基类的内存布局是已知的。

    - 所请求的 `PyType_Spec.basicsize` 为零，表明子类不会直接访问实例的内存。

    - 具有 `Py_TPFLAGS_ITEMS_AT_END` 旗标。

  unsigned int flags

    Type flags, used to set `PyTypeObject.tp_flags`.

    If the `Py_TPFLAGS_HEAPTYPE` flag is not set, `PyType_FromSpecWithBases()` sets it automatically.

  PyType_Slot *slots

    Array of `PyType_Slot` structures. Terminated by the special slot value `{0, NULL}`.

    Each slot ID should be specified at most once.

type PyType_Slot
  属于 稳定 ABI （包括所有成员）.

  Structure defining optional functionality of a type, containing a slot ID and a value pointer.

  int slot

    A slot ID.

    Slot IDs are named like the field names of the structures `PyTypeObject`, `PyNumberMethods`, `PySequenceMethods`, `PyMappingMethods` and `PyAsyncMethods` with an added `Py_` prefix. For example, use:

    - `Py_tp_dealloc` 用于设置 `PyTypeObject.tp_dealloc`

    - `Py_nb_add` 用于设置 `PyNumberMethods.nb_add`

    - `Py_sq_length` 用于设置 `PySequenceMethods.sq_length`

    An additional slot is supported that does not correspond to a `PyTypeObject` struct field:

    - `Py_tp_token`

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

    - `tp_weaklistoffset` (如果可能请改用 `Py_TPFLAGS_MANAGED_WEAKREF`)

    - `tp_dictoffset` (如果可能请改用 `Py_TPFLAGS_MANAGED_DICT`)

    - `tp_vectorcall_offset` (请使用 PyMemberDef 中的 `"__vectorcalloffset__"`)

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

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

    - `tp_dict`, `tp_mro`, `tp_cache`, `tp_subclasses` 和 `tp_weaklist`。

    Setting `Py_tp_bases` or `Py_tp_base` may be problematic on some platforms. To avoid issues, use the bases argument of `PyType_FromSpecWithBases()` instead.

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

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

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

  void *pfunc

    The desired value of the slot. In most cases, this is a pointer to a function.

    pfunc values may not be `NULL`, except for the following slots:

    - `Py_tp_doc`

    - `Py_tp_token` (为了清晰起见，建议使用 `Py_TP_USE_SPEC` 而不是 `NULL`)

Py_tp_token
  属于 稳定 ABI 自 3.14 版起.

  A `slot` that records a static memory layout ID for a class.

  If the `PyType_Spec` of the class is statically allocated, the token can be set to the spec using the special value `Py_TP_USE_SPEC`:

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

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

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

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

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

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

  Added in version 3.14.

  Py_TP_USE_SPEC
    属于 稳定 ABI 自 3.14 版起.

    Used as a value with `Py_tp_token` to set the token to the class's `PyType_Spec`. Expands to `NULL`.

    Added in version 3.14.