[Cython] Python C-api ref count semantics
Stefan Behnel
stefan_ml at behnel.de
Fri Feb 18 05:54:48 CET 2011
Chris Colbert, 18.02.2011 03:23:
> What is the rule of thumb when declaring functions from python's C-api when
> comes to ref counting?
The general rule is to not declare them yourself. Instead, cimport them
from the cpython package. (See Cython/Includes/)
> If I define a test case like so:
>
> cdef extern from "Python.h":
>
> object PyWeakref_NewRef(object, object)
> object PyWeakref_GET_OBJECT(object)
>
>
> class Foo(object):
> pass
>
>
> cdef class Test:
>
> cdef object obj
> cdef object wr
>
> def __init__(self):
> self.obj = Foo()
> self.wr = PyWeakref_NewRef(self.obj, None)
>
> def get_ref(self):
> return PyWeakref_GET_OBJECT(self.wr)
>
>
> I get these random python fatal errors:
>
> In [8]: %timeit -n 1000 t.get_ref()
> 1000 loops, best of 3: 224 ns per loop
>
> In [9]: %timeit -n 1000 t.get_ref()
> Fatal Python error: deallocating None
> Abort trap
>
>
> However, if I redefine the macro signature and getter function to this:
>
> from cpython cimport PyObject
>
> cdef extern from "Python.h":
>
> object PyWeakref_NewRef(object, object)
> PyObject* PyWeakref_GET_OBJECT(object)
>
>
> class Foo(object):
> pass
>
>
> cdef class Test:
>
> cdef object obj
> cdef object wr
>
> def __init__(self):
> self.obj = Foo()
> self.wr = PyWeakref_NewRef(self.obj, None)
>
> def clear_obj(self):
> self.obj = None
>
> def get_ref(self):
> return<object>PyWeakref_GET_OBJECT(self.wr)
>
>
> Then it runs without issue. I can other gather is has to due the
> incref/decref going on in the generated C code. Should be doing something on
> my end to manually manage ref counts when using the C-Api?
Check the CPython documentation. Whenever a function returns a borrowed
reference, you must declare it as PyObject* and cast it to <object>.
That being said, support for borrowed references has been long on the list
but no-one has shown interest in doing it (or getting it done) so far.
Stefan
More information about the cython-devel
mailing list