使对象类型支持循环垃圾回收
**************************

Python 对循环引用的垃圾检测与回收需要“容器”对象类型的支持，此类型的容
器对象中可能包含其它容器对象。不保存其它对象的引用的类型，或者只保存原
子类型（如数字或字符串）的引用的类型，不需要显式提供垃圾回收的支持。

要创建一个容器类，类型对象的 "tp_flags" 字段必须包括
"Py_TPFLAGS_HAVE_GC" 并提供一个 "tp_traverse" 处理器的实现。如果该类型
的实例是可变的，则还必须提供 "tp_clear" 的实现。

"Py_TPFLAGS_HAVE_GC"
   设置了此标志位的类型的对象必须符合此处记录的规则。为方便起见，下文
   把这些对象称为容器对象。

容器类型的构造函数必须符合两个规则：

1. 该对象的内存必须使用 "PyObject_GC_New" 或 "PyObject_GC_NewVar" 来分
   配。

2. 初始化了所有可能包含其他容器的引用的字段后，它必须调用
   "PyObject_GC_Track()"。

同样的，对象的释放器必须符合两个类似的规则：

1. 在引用其它容器的字段失效前，必须调用 "PyObject_GC_UnTrack()"。

2. 必须使用 "PyObject_GC_Del()" 释放对象的内存。

   警告:

     如果一个类型添加了 Py_TPFLAGS_HAVE_GC，则它 *必须* 实现至少一个
     "tp_traverse" 句柄或显式地使用来自其一个或多个子类的句柄。当调用
     "PyType_Ready()" 或者某些间接调用该函数的 API 如
     "PyType_FromSpecWithBases()" 或 "PyType_FromSpec()" 时解释器将自
     动填充 "tp_flags", "tp_traverse" 和 "tp_clear" 字段，如果该类型是
     继承自实现了垃圾回收器协议的类并且该子类 *没有* 包括
     "Py_TPFLAGS_HAVE_GC" 旗标的话。

PyObject_GC_New(TYPE, typeobj)

   类似于 "PyObject_New" 但专用于设置了 "Py_TPFLAGS_HAVE_GC" 旗标的容
   器对象。

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

   在填充类型的 "tp_alloc" 槽位时，推荐使用 "PyType_GenericAlloc()" 而
   不是使用简单调用此宏的自定义函数。

   由此宏分配的内存必须用 "PyObject_GC_Del()" 来释放（通常是通过对象的
   "tp_free" 槽位来调用）。

   参见:

     * "PyObject_GC_Del()"

     * "PyObject_New"

     * "PyType_GenericAlloc()"

     * "tp_alloc"

PyObject_GC_NewVar(TYPE, typeobj, size)

   与 "PyObject_NewVar" 类似但专用于设置了 "Py_TPFLAGS_HAVE_GC" 旗标的
   容器对象。

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

   在填充类型的 "tp_alloc" 槽位时，推荐使用 "PyType_GenericAlloc()" 而
   不是使用简单调用此宏的自定义函数。

   由此宏分配的内存必须用 "PyObject_GC_Del()" 来释放（通常是通过对象的
   "tp_free" 槽位来调用）。

   参见:

     * "PyObject_GC_Del()"

     * "PyObject_NewVar"

     * "PyType_GenericAlloc()"

     * "tp_alloc"

PyObject *PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *type, size_t extra_size)

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

   与 "PyObject_GC_New" 类似但会在对象的末尾分配 *extra_size* 个字节（
   在 "tp_basicsize" 偏移量处）。除 "Python 对象标头" 外，分配的内存将
   初始化为零。

   附加数据将与对象一起被释放，但在其他情况下则不会由 Python 来管理。

   由此函数分配的内存必须用 "PyObject_GC_Del()" 来释放（通常是通过对象
   的 "tp_free" 槽位来调用）。

   警告:

     此函数被标记为非稳定的因为在实例之后保留附加数据的机制尚未确定。
     要分配可变数量的字段，推荐改用 "PyVarObject" 和 "tp_itemsize" 字
     段。

   Added in version 3.12.

PyObject_GC_Resize(TYPE, op, newsize)

   重新调整 "PyObject_NewVar" 所分配对象的大小。返回调整大小后的类型为
   "TYPE*" 的对象（指向任意 C 类型）或在失败时返回 "NULL"。

   *op* 必须为 PyVarObject* 类型并且不能已被回收器所追踪。 *newsize*
   必须为 "Py_ssize_t" 类型。

void PyObject_GC_Track(PyObject *op)
    * 属于 稳定 ABI.*

   把对象 *op* 加入到垃圾回收器跟踪的容器对象中。对象在被回收器跟踪时
   必须保持有效的，因为回收器可能在任何时候开始运行。在 "tp_traverse"
   处理前的所有字段变为有效后，必须调用此函数，通常在靠近构造函数末尾
   的位置。

int PyObject_IS_GC(PyObject *obj)

   如果对象实现了垃圾回收器协议则返回非零值，否则返回 0。

   如果此函数返回 0 则对象无法被垃圾回收器追踪。

int PyObject_GC_IsTracked(PyObject *op)
    * 属于 稳定 ABI 自 3.9 版起.*

   如果 *op* 对象的类型实现了 GC 协议且 *op* 目前正被垃圾回收器追踪则
   返回 1，否则返回 0。

   这类似于 Python 函数 "gc.is_tracked()"。

   Added in version 3.9.

int PyObject_GC_IsFinalized(PyObject *op)
    * 属于 稳定 ABI 自 3.9 版起.*

   如果 *op* 对象的类型实现了 GC 协议且 *op* 已经被垃圾回收器终结则返
   回 1，否则返回 0。

   这类似于 Python 函数 "gc.is_finalized()"。

   Added in version 3.9.

void PyObject_GC_Del(void *op)
    * 属于 稳定 ABI.*

   释放之前使用 "PyObject_GC_New" 或 "PyObject_GC_NewVar" 分配给对象的
   内存。

   请不要直接调用此函数来释放对象的内存；而应调用类型的 "tp_free" 槽位
   。

   请不要为由 "PyObject_New", "PyObject_NewVar" 或相关联的分配函数分配
   的内存使用此宏；而应改用 "PyObject_Free()"。

   参见:

     * "PyObject_Free()" 是此函数的非 GC 对应物。

     * "PyObject_GC_New"

     * "PyObject_GC_NewVar"

     * "PyType_GenericAlloc()"

     * "tp_free"

void PyObject_GC_UnTrack(void *op)
    * 属于 稳定 ABI.*

   从回收器跟踪的容器对象集合中移除 *op* 对象。请注意可以在此对象上再
   次调用 "PyObject_GC_Track()" 以将其加回到被跟踪对象集合。释放器
   ("tp_dealloc" 句柄) 应当在 "tp_traverse" 句柄所使用的任何字段失效之
   前为对象调用此函数。

在 3.8 版本发生变更: "_PyObject_GC_TRACK()" 和
"_PyObject_GC_UNTRACK()" 宏已从公有 C API 中删除。

"tp_traverse" 处理接收以下类型的函数形参。

typedef int (*visitproc)(PyObject *object, void *arg)
    * 属于 稳定 ABI.*

   传给 "tp_traverse" 处理的访问函数的类型。*object* 是容器中需要被遍
   历的一个对象，第三个形参对应于 "tp_traverse" 处理的 *arg* 。Python
   核心使用多个访问者函数实现循环引用的垃圾检测，不需要用户自行实现访
   问者函数。

"tp_clear" 处理程序必须为 "inquiry" 类型，如果对象不可变则为 "NULL" 值
。

typedef int (*inquiry)(PyObject *self)
    * 属于 稳定 ABI.*

   丢弃产生循环引用的引用。不可变对象不需要声明此方法，因为它们不可能
   直接产生循环引用。需要注意的是，对象在调用此方法后必须仍是有效的（
   不能对引用只调用 "Py_DECREF()" 方法）。当垃圾回收器检测到该对象在循
   环引用中时，此方法会被调用。


遍历
====

"tp_traverse" 处理必须是以下类型：

typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg)
    * 属于 稳定 ABI.*

   针对垃圾收集对象的遍历函数，被垃圾收集器用于检测引用循环。 具体实现
   必须为 *self* 直接包含的每个对象调用 *visit* 函数，传给 *visit* 的
   形参为所包含对象和传给处理器的 *arg* 值。 *visit* 函数调用不可附带
   "NULL" 对象作为参数。 如果 *visit* 返回非零值，则该值应当被立即返回
   。

   一个典型的 "tp_traverse" 函数会在实例所拥有的每个属于 Python 对象的
   实例成员上调用 "Py_VISIT()" 便捷宏。 例如，下面是一个针对
   "threading.local" 类的（略微过时的）遍历函数:

      static int
      local_traverse(PyObject *op, visitproc visit, void *arg)
      {
          localobject *self = (localobject *) op;
          Py_VISIT(Py_TYPE(self));
          Py_VISIT(self->args);
          Py_VISIT(self->kw);
          Py_VISIT(self->dict);
          return 0;
      }

   备注:

     "Py_VISIT()" 要求传给 "local_traverse()" 的 *visit* 和 *arg* 形参
     具有这些指定名称；请不要随意命名它们。

   堆分配类型 的实例会持有一个对其类型的引用。 因此它们的遍历函数必须
   访问其类型:

      Py_VISIT(Py_TYPE(self));

   Alternately, the type may delegate this responsibility by calling
   "tp_traverse" of a heap-allocated superclass (or another heap-
   allocated type, if applicable). If they do not, the type object may
   not be garbage-collected.

   如果在 "tp_flags" 字段中设置了 "Py_TPFLAGS_MANAGED_DICT" 比特位，则
   遍历函数必须这样调用 "PyObject_VisitManagedDict()":

      int err = PyObject_VisitManagedDict((PyObject*)self, visit, arg);
      if (err) {
          return err;
      }

   Only the members that the instance *owns* (by having *strong
   references* to them) must be visited. For instance, if an object
   supports weak references via the "tp_weaklist" slot, the pointer
   supporting the linked list (what *tp_weaklist* points to) must
   **not** be visited as the instance does not directly own the weak
   references to itself.

   The traversal function has a limitation:

   警告:

     The traversal function must not have any side effects.
     Implementations may not modify the reference counts of any Python
     objects nor create or destroy any Python objects, directly or
     indirectly.

   This means that *most* Python C API functions may not be used,
   since they can raise a new exception, return a new reference to a
   result object, have internal logic that uses side effects. Also,
   unless documented otherwise, functions that happen to not have side
   effects may start having them in future versions, without warning.

   For a list of safe functions, see a separate section below.

   备注:

     The "Py_VISIT()" call may be skipped for those members that
     provably cannot participate in reference cycles. In the
     "local_traverse" example above, there is also a "self->key"
     member, but it can only be "NULL" or a Python string and
     therefore cannot be part of a reference cycle.在另一方面，即使你
     知道某个成员永远不会成为循环引用的一部分，作为调试的辅助你仍然可
     能想要访问它因此 "gc" 模块的 "get_referents()" 函数将会包括它。

   备注:

     "tp_traverse" 函数可以从任何线程调用。

     **CPython 实现细节：** Garbage collection is a "stop-the-world"
     operation: even in *free threading* builds, only one thread state
     is *attached* when "tp_traverse" handlers run.

   在 3.9 版本发生变更: 堆分配类型应当访问 "tp_traverse" 中的
   "Py_TYPE(self)"。在较早的 Python 版本中，由于 bug 40217，这样做可能
   会导致在子类中发生崩溃。

To simplify writing "tp_traverse" handlers, a "Py_VISIT()" macro is
provided. In order to use this macro, the "tp_traverse" implementation
must name its arguments exactly *visit* and *arg*:

Py_VISIT(o)

   If the PyObject* *o* is not "NULL", call the *visit* callback, with
   arguments *o* and *arg*. If *visit* returns a non-zero value, then
   return it.

   This corresponds roughly to:

      #define Py_VISIT(o)                             \
         if (op) {                                    \
            int visit_result = visit(o, arg);         \
            if (visit_result != 0) {                  \
               return visit_result;                   \
            }                                         \
         }


Traversal-safe functions
------------------------

The following functions and macros are safe to use in a "tp_traverse"
handler:

* the *visit* function passed to "tp_traverse"

* "Py_VISIT()"

* "Py_SIZE()"

* "Py_TYPE()": if called from a "tp_traverse" handler, "Py_TYPE()"'s
  result will be valid for the duration of the handler call

* "PyObject_VisitManagedDict()"

* "PyObject_TypeCheck()", "PyType_IsSubtype()", "PyType_HasFeature()"

* "Py*<type>*_Check" and "Py*<type>*_CheckExact" -- for example,
  "PyTuple_Check()"

* "DuringGC" functions


"DuringGC" functions
--------------------

The following functions should *only* be used in a "tp_traverse"
handler; calling them in other contexts may have unintended
consequences.

These functions act like their counterparts without the "_DuringGC"
suffix, but they are guaranteed to not have side effects, they do not
set an exception on failure, and they return/set *borrowed references*
as detailed in the individual documentation.

Note that these functions may fail (return "NULL" or "-1"), but as
they do not set an exception, no error information is available. In
some cases, failure is not distinguishable from a successful "NULL"
result.

void *PyObject_GetTypeData_DuringGC(PyObject *o, PyTypeObject *cls)
void *PyObject_GetItemData_DuringGC(PyObject *o)
void *PyType_GetModuleState_DuringGC(PyTypeObject *type)
void *PyModule_GetState_DuringGC(PyObject *module)
int PyModule_GetToken_DuringGC(PyObject *module, void **result)
    * 属于 稳定 ABI 自 3.15 版起.*

   See "DuringGC" functions for common information.

   Added in version 3.15.

   参见:

     "PyObject_GetTypeData()", "PyObject_GetItemData()",
     "PyType_GetModuleState()", "PyModule_GetState()",
     "PyModule_GetToken()", "PyType_GetBaseByToken()"

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

   See "DuringGC" functions for common information.

   Sets **result* to a *borrowed reference* rather than a strong one.
   The reference is valid for the duration of the "tp_traverse"
   handler call.

   Added in version 3.15.

   参见: "PyType_GetBaseByToken()"

PyObject *PyType_GetModule_DuringGC(PyTypeObject *type)
PyObject *PyType_GetModuleByToken_DuringGC(PyTypeObject *type, const void *mod_token)
    *返回值：借入的引用。** 属于 稳定 ABI 自 3.15 版起.*

   See "DuringGC" functions for common information.

   这些函数将返回 *borrowed reference*，它会在 "tp_traverse" 处理器调
   用持续期间保持可用。

   Added in version 3.15.

   参见: "PyType_GetModule()", "PyType_GetModuleByToken()"


控制垃圾回收器状态
==================

这个 C-API 提供了以下函数用于控制垃圾回收的运行。

Py_ssize_t PyGC_Collect(void)
    * 属于 稳定 ABI.*

   执行完全的垃圾回收，如果垃圾回收器已启用的话。 （请注意
   "gc.collect()" 会无条件地执行它。）

   返回已回收的 + 无法回收的不可获取对象的数量。如果垃圾回收器被禁用或
   已在执行回收，则立即返回 "0"。在垃圾回收期间发生的错误会被传给
   "sys.unraisablehook"。此函数不会引发异常。

int PyGC_Enable(void)
    * 属于 稳定 ABI 自 3.10 版起.*

   启用垃圾回收器：类似于 "gc.enable()"。返回之前的状态，0 为禁用而 1
   为启用。

   Added in version 3.10.

int PyGC_Disable(void)
    * 属于 稳定 ABI 自 3.10 版起.*

   禁用垃圾回收器：类似于 "gc.disable()"。返回之前的状态，0 为禁用而 1
   为启用。

   Added in version 3.10.

int PyGC_IsEnabled(void)
    * 属于 稳定 ABI 自 3.10 版起.*

   查询垃圾回收器的状态：类似于 "gc.isenabled()"。返回当前的状态，0 为
   禁用而 1 为启用。

   Added in version 3.10.


查询垃圾回收器状态
==================

该 C-API 提供了以下接口用于查询有关垃圾回收器的信息。

void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg)

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

   在全部活动的支持 GC 的对象上运行所提供的 *callback*。 *arg* 会被传
   递给所有 *callback* 的调用。

   警告:

     如果新对象被回调所（取消）分配，则它们是否会被访问是未定义的。垃
     圾回收在运行期间被禁用。在回调中显式地运行回收可能导致未定义的行
     为，例如多次访问同一对象或完全不访问。

   Added in version 3.12.

typedef int (*gcvisitobjects_t)(PyObject *object, void *arg)

   要传给 "PyUnstable_GC_VisitObjects()" 的访问者函数的类型。 *arg* 与
   传给 "PyUnstable_GC_VisitObjects" 的 *arg* 相同。返回 "1" 以继续迭
   代，返回 "0" 以停止迭代。 其他返回值目前被保留因此返回任何其他值的
   行为都是未定义的。

   Added in version 3.12.
