[Cython] Python C-api ref count semantics

Chris Colbert sccolbert at gmail.com
Fri Feb 18 03:23:54 CET 2011


What is the rule of thumb when declaring functions from python's C-api when
comes to ref counting?

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?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20110217/a4c6093a/attachment.html>


More information about the cython-devel mailing list