PyObject* 是由 PyModule_Create 'borrowed' 还是 'acquired' 返回的?

Is the PyObject* returned by PyModule_Create 'borrowed' or 'acquired'?

latest Python Doc 只说了 PyModule_Create:

The module initialization function may create and return the module object directly. This is referred to as “single-phase initialization”, and uses one of the following two module creation functions:

PyObject* PyModule_Create(PyModuleDef *def)

  • Create a new module object, given the definition in def. This behaves like PyModule_Create2() with module_api_version set to PYTHON_API_VERSION.
  • ...

Before it is returned from in the initialization function, the resulting module object is typically populated using functions like PyModule_AddObject().

此外,PyModule_Create 不在 this question 的列表中。这表明正在遵循常规行为,即调用者应 'acquire' 返回对 PyObject* 的引用。

但是从这个 python3porting 博客 post,它有以下示例:

static PyObject *
moduleinit(void)
{
  MOD_DEF(m, "themodulename",
          "This is the module docstring",
  module_methods)

  if (m == NULL)
      return NULL;

  if (PyModule_AddObject(m, "hookable",
         (PyObject *)&hookabletype) < 0)
      return NULL;                         /* line A */

  return m;
}

'line A' 不会泄漏此代码路径的引用吗? PyModule_Create 的正确用法和所有权语义是什么?

该代码段根本没有正确管理引用计数。除了您发现的泄漏之外,它还忘记了 Py_INCREF(&hookabletype),尽管 PyModule_AddObject steals a reference to the value.

与往常一样,如无特别说明,PyModule_Create returns 新引用,而非借用引用。