File: clear_to_null.pyx

package info (click to toggle)
cython 3.0.11%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 19,092 kB
  • sloc: python: 83,539; ansic: 18,831; cpp: 1,402; xml: 1,031; javascript: 511; makefile: 403; sh: 204; sed: 11
file content (68 lines) | stat: -rw-r--r-- 1,870 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""
Check that Cython generates a tp_clear function that actually clears object
references to NULL instead of None.

Discussed here: https://article.gmane.org/gmane.comp.python.cython.devel/14833
"""

from cpython.ref cimport PyObject, Py_TYPE

cdef class ExtensionType:
    """
    Just a type which is handled by a specific C type (instead of PyObject)
    to check that tp_clear works when the C pointer is of a type different
    from PyObject *.
    """


# Pull tp_clear for PyTypeObject as I did not find another way to access it
# from Cython code.

cdef extern from "Python.h":
    ctypedef struct PyTypeObject:
        void (*tp_clear)(object)


cdef class TpClearFixture:
    """
    An extension type that has a tp_clear method generated to test that it
    actually clears the references to NULL.

    >>> fixture = TpClearFixture()
    >>> isinstance(fixture.extension_type, ExtensionType)
    True
    >>> isinstance(fixture.any_object, str)
    True
    >>> fixture.call_tp_clear()
    >>> fixture.check_any_object_status()
    'NULL'
    >>> fixture.check_extension_type_status()
    'NULL'
    """
    
    cdef readonly object any_object
    cdef readonly ExtensionType extension_type

    def __cinit__(self):
        self.any_object = "Hello World"
        self.extension_type = ExtensionType()

    def call_tp_clear(self):
        cdef PyTypeObject *pto = Py_TYPE(self)
        pto.tp_clear(self)

    def check_any_object_status(self):
        if <void*>(self.any_object) == NULL:
            return 'NULL'
        elif self.any_object is None:
            return 'None' 
        else:
            return 'not cleared'

    def check_extension_type_status(self):
        if <void*>(self.any_object) == NULL:
            return 'NULL'
        elif self.any_object is None:
            return 'None' 
        else:
            return 'not cleared'