【问题标题】:Is the PyObject* returned by PyModule_Create 'borrowed' or 'acquired'?PyModule_Create 返回的 PyObject* 是“借来的”还是“获得的”?
【发布时间】:2017-02-13 00:10:25
【问题描述】:

latest Python Doc 只说PyModule_Create

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

PyObject* PyModule_Create(PyModuleDef *def)

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

在从初始化函数中返回之前,生成的模块对象通常使用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 的正确用法和所有权语义是什么?

【问题讨论】:

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


    【解决方案1】:

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

    像往常一样,如果没有特别说明,PyModule_Create 返回一个新的引用,而不是借来的引用。

    【讨论】:

    • 好的,这是有道理的。因此,如果您需要指示模块加载错误 PyModule_Create 已经成功,那么Py_DECREF(m) 是必要的吗?
    猜你喜欢
    • 2021-03-19
    • 2015-02-12
    • 1970-01-01
    • 2015-02-25
    • 2011-11-10
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多