是否总是需要增加Py_True / Py_False引用计数?

问题描述 投票:2回答:1

我是Python C-API的新手,正在浏览一些源代码以挑选其中的一部分。

这里是我在包含扩展模块的程序包的C源代码中找到的函数的最低版本:

#define PY_SSIZE_T_CLEAN
#include <Python.h>

static PyObject *
modulename_myfunc(PyObject *self, PyObject *args) {

    // Call PyArg_ParseTuple, etc ...

    // Dummy values; in the real function they are calculated
    int is_found = 1;
    Py_ssize_t n_bytes_found = 1024;

    PyObject *result;
    result = Py_BuildValue("(Oi)",
                           is_found ? Py_True : Py_False,  // Py_INCREF?
                           n_bytes_found);
    return result;
}

这是否通过在Py_INCREFPy_True上不使用Py_False引起了小的内存泄漏? C-API docs for Boolean object似乎很明确,总是需要增加/拒绝Py_TruePy_False

如果确实需要引入Py_INCREF,假设Py_RETURN_TRUE / Py_RETURN_FALSE因为返回了元组而实际上并不适用,那么如何在这里最合适地使用它?

python c python-3.x python-c-api
1个回答
2
投票

此处未使用Py_INCREF的原因是,Py_BuildValue在传递给对象时带有“ O”将为您增加引用计数:

O(对象)[PyObject *]

[传递Python对象时保持不变(其引用计数增加一,但引用计数除外)。如果传入的对象是NULL指针,则认为这是由于产生该参数的调用发现错误并设置异常而引起的。因此,Py_BuildValue()将返回NULL,但不会引发异常。如果尚未引发异常,则设置SystemError。

例如,您将在CPython Py_BuildValue中看到类似的用法。

© www.soinside.com 2019 - 2024. All rights reserved.