Blame tests/run/clear_to_null.pyx

Packit 562c7a
"""
Packit 562c7a
Check that Cython generates a tp_clear function that actually clears object
Packit 562c7a
references to NULL instead of None.
Packit 562c7a
Packit 562c7a
Discussed here: http://article.gmane.org/gmane.comp.python.cython.devel/14833
Packit 562c7a
"""
Packit 562c7a
Packit 562c7a
from cpython.ref cimport PyObject, Py_TYPE
Packit 562c7a
Packit 562c7a
cdef class ExtensionType:
Packit 562c7a
    """
Packit 562c7a
    Just a type which is handled by a specific C type (instead of PyObject)
Packit 562c7a
    to check that tp_clear works when the C pointer is of a type different
Packit 562c7a
    from PyObject *.
Packit 562c7a
    """
Packit 562c7a
Packit 562c7a
Packit 562c7a
# Pull tp_clear for PyTypeObject as I did not find another way to access it
Packit 562c7a
# from Cython code.
Packit 562c7a
Packit 562c7a
cdef extern from "Python.h":
Packit 562c7a
    ctypedef struct PyTypeObject:
Packit 562c7a
        void (*tp_clear)(object)
Packit 562c7a
Packit 562c7a
Packit 562c7a
cdef class TpClearFixture:
Packit 562c7a
    """
Packit 562c7a
    An extension type that has a tp_clear method generated to test that it
Packit 562c7a
    actually clears the references to NULL.
Packit 562c7a
Packit 562c7a
    >>> fixture = TpClearFixture()
Packit 562c7a
    >>> isinstance(fixture.extension_type, ExtensionType)
Packit 562c7a
    True
Packit 562c7a
    >>> isinstance(fixture.any_object, str)
Packit 562c7a
    True
Packit 562c7a
    >>> fixture.call_tp_clear()
Packit 562c7a
    >>> fixture.check_any_object_status()
Packit 562c7a
    'NULL'
Packit 562c7a
    >>> fixture.check_extension_type_status()
Packit 562c7a
    'NULL'
Packit 562c7a
    """
Packit 562c7a
    
Packit 562c7a
    cdef readonly object any_object
Packit 562c7a
    cdef readonly ExtensionType extension_type
Packit 562c7a
Packit 562c7a
    def __cinit__(self):
Packit 562c7a
        self.any_object = "Hello World"
Packit 562c7a
        self.extension_type = ExtensionType()
Packit 562c7a
Packit 562c7a
    def call_tp_clear(self):
Packit 562c7a
        cdef PyTypeObject *pto = Py_TYPE(self)
Packit 562c7a
        pto.tp_clear(self)
Packit 562c7a
Packit 562c7a
    def check_any_object_status(self):
Packit 562c7a
        if <void*>(self.any_object) == NULL:
Packit 562c7a
            return 'NULL'
Packit 562c7a
        elif self.any_object is None:
Packit 562c7a
            return 'None' 
Packit 562c7a
        else:
Packit 562c7a
            return 'not cleared'
Packit 562c7a
Packit 562c7a
    def check_extension_type_status(self):
Packit 562c7a
        if <void*>(self.any_object) == NULL:
Packit 562c7a
            return 'NULL'
Packit 562c7a
        elif self.any_object is None:
Packit 562c7a
            return 'None' 
Packit 562c7a
        else:
Packit 562c7a
            return 'not cleared'