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
_______________________________________________
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel

Reply via email to