I l@ve RuBoard |
16.5 Returning None from a Python-Callable C FunctionCredit: Alex Martelli 16.5.1 ProblemYour C-coded, Python-callable function in an extension module needs to return nothing in particular (i.e., a Python None), but it must, of course, do so without messing up reference counts. 16.5.2 SolutionSuppose we need an empty, C-coded function equivalent to Python: def empty1(*args): pass or, identically: def empty2(*args): return None there is still a right and a wrong way to solve the problem. The wrong way messes up reference counts: static PyObject* empty3(PyObject* self, PyObject* args) { return Py_None; } But it's not hard to do it right. Here is the simplest way: static PyObject*
empty4(PyObject* self, PyObject* args)
{
return Py_BuildValue("");
}
And here is the canonical way: static PyObject* empty5(PyObject* self, PyObject* args) { Py_INCREF(Py_None); return Py_None; } 16.5.3 DiscussionOften, a function written in C for Python needs to return nothing in particular. In other words, it should return None in Python terms, but you can't return Py_None from C, because that will mess up reference counts. None�the Python object we must explicitly return from a Python-callable, C-coded function�is a perfectly normal Python object, still subject to all normal reference-count rules. One of these rules is that each function must Py_INCREF the Python object it returns. So a bare return Py_None; is a nasty lurking bug. Either explicitly Py_INCREF the None object you're returning, or delegate the work to handy function Py_BuildValue (simpler, but costs a few machine cycles), which can be used to handle just about all cases of returning values from C to Python, offering potential uniformity advantages. To have Py_BuildValue build a properly incremented None on your behalf, call it with an empty format string. 16.5.4 See AlsoThe Extending and Embedding manual is available as part of the standard Python documentation set at http://www.python.org/doc/current/ext/ext.html; documentation on the Python C API at http://www.python.org/doc/current/api/api.html. |
I l@ve RuBoard |