PyModule_Create返回的PyObject *是'借用'还是'获得'?

时间:2017-02-13 00:10:25

标签: c python-3.x python-c-api reference-counting

latest Python Doc仅对PyModule_Create

说了这个
  

模块初始化函数可以直接创建和返回模块对象。这称为“单相初始化”,并使用以下两个模块创建函数之一:

     

PyObject* PyModule_Create(PyModuleDef *def)

     
      
  • 根据 def 中的定义创建一个新模块对象。其行为类似于PyModule_Create2(),其中 module_api_version 设置为PYTHON_API_VERSION
  •   
  • ...
  •   
     

在初始化函数返回之前,生成的模块对象通常使用PyModule_AddObject()等函数填充。

此外,PyModule_Create不在this question的列表中。这表明正在遵循传统行为,即调用者应该“获得”对返回的PyObject*的引用。

但是,从这篇python3porting博文中,它有以下示例:

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;
}

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

1 个答案:

答案 0 :(得分:4)

该代码段不能正确管理引用计数。除了你发现的泄漏之外,它还会忘记Py_INCREF(&hookabletype),尽管事实是PyModule_AddObject steals a reference to the value

通常在没有另行规定的情况下,PyModule_Create会返回一个新的引用,而不是借来的引用。