File: nanobind3.c

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (120 lines) | stat: -rw-r--r-- 3,141 bytes parent folder | download | duplicates (4)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <Python.h>
#include <structmember.h>

// ----------------------------------------------------

PyObject* global_list = NULL;

static int my_object_init(PyObject *self, PyObject *args, PyObject *kwds) {
    PyList_Append(global_list, PyUnicode_FromString("my_object tp_init called."));
    return 0;
}

static void my_object_dealloc(PyObject *self) {
    PyList_Append(global_list, PyUnicode_FromString("my_object tp_dealloc called."));
    PyTypeObject *tp = Py_TYPE(self);
    tp->tp_free(self);
    Py_DECREF(tp);
}


static PyType_Slot my_object_slots[] = {
    { Py_tp_init, my_object_init },
    { Py_tp_dealloc, my_object_dealloc },
    { 0, NULL }
};

static PyType_Spec my_object_spec = {
    .name = "nanobind3.my_object",
    .flags = Py_TPFLAGS_DEFAULT,
    .slots = my_object_slots,
    .basicsize = (int) sizeof(PyObject),
    .itemsize = 0
};

// ----------------------------------------------------

typedef struct {
    PyObject_HEAD
    PyObject* (*vectorcall)(PyObject *, PyObject * const*, size_t, PyObject *);
} my_callable;


PyObject* my_vectorcall(PyObject *self, PyObject * const* args, size_t nargs,
                        PyObject *kwnames) {
    PyList_Append(global_list, PyUnicode_FromString(
		"my_callable(*args, **kwargs) called -- raising an exception"));
    PyErr_SetString(PyExc_ValueError, "oops, an exception!");
    return NULL;
}

static int my_callable_init(PyObject *self, PyObject *args, PyObject *kwds) {
    ((my_callable *) self)->vectorcall = my_vectorcall;
    return 0;
}

static struct PyMemberDef my_callable_members[] = {
    // Supported starting with Python 3.9
    { "__vectorcalloffset__", T_PYSSIZET,
      (Py_ssize_t) offsetof(my_callable, vectorcall), READONLY, NULL },
     { NULL, 0, 0, 0, NULL }
};

static PyType_Slot my_callable_slots[] = {
    { Py_tp_init, my_callable_init },
    { Py_tp_members, my_callable_members },
    { Py_tp_call, (void *) PyVectorcall_Call },
    { 0, NULL }
};

static PyType_Spec my_callable_spec = {
    .name = "nanobind3.my_callable",
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_VECTORCALL,
    .slots = my_callable_slots,
    .basicsize = (int) sizeof(my_callable),
    .itemsize = 0
};


static PyModuleDef pypy_issues_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "nanobind3",
    .m_doc = "Reproducer for issue 3854",
    .m_size = -1
};

PyMODINIT_FUNC
PyInit_nanobind3(void)
{
    PyObject *m = PyModule_Create(&pypy_issues_module);
    if (m == NULL) {
        return NULL;
    }

    global_list = PyList_New(0);

    if (!global_list || PyModule_AddObject(m, "global_list", global_list) < 0) {
        Py_XDECREF(global_list);
        Py_DECREF(m);
        return NULL;
    }

    PyObject *my_object = PyType_FromSpec(&my_object_spec);

    if (!my_object || PyModule_AddObject(m, "my_object", my_object) < 0) {
        Py_XDECREF(my_object);
        Py_DECREF(m);
        return NULL;
    }

    PyObject *func = PyType_FromSpec(&my_callable_spec);

    if (!func || PyModule_AddObject(m, "my_callable", func) < 0) {
        Py_XDECREF(func);
        Py_DECREF(m);
        return NULL;
    }

    return m;
}