17db96d56Sopenharmony_ci/* Use this file as a template to start implementing a module that 27db96d56Sopenharmony_ci also declares object types. All occurrences of 'Xxo' should be changed 37db96d56Sopenharmony_ci to something reasonable for your objects. After that, all other 47db96d56Sopenharmony_ci occurrences of 'xx' should be changed to something reasonable for your 57db96d56Sopenharmony_ci module. If your module is named foo your source file should be named 67db96d56Sopenharmony_ci foo.c or foomodule.c. 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci You will probably want to delete all references to 'x_attr' and add 97db96d56Sopenharmony_ci your own types of attributes instead. Maybe you want to name your 107db96d56Sopenharmony_ci local variables other than 'self'. If your object type is needed in 117db96d56Sopenharmony_ci other files, you'll have to create a file "foobarobject.h"; see 127db96d56Sopenharmony_ci floatobject.h for an example. 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci This module roughly corresponds to:: 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci class Xxo: 177db96d56Sopenharmony_ci """A class that explicitly stores attributes in an internal dict""" 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci def __init__(self): 207db96d56Sopenharmony_ci # In the C class, "_x_attr" is not accessible from Python code 217db96d56Sopenharmony_ci self._x_attr = {} 227db96d56Sopenharmony_ci self._x_exports = 0 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci def __getattr__(self, name): 257db96d56Sopenharmony_ci return self._x_attr[name] 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci def __setattr__(self, name, value): 287db96d56Sopenharmony_ci self._x_attr[name] = value 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci def __delattr__(self, name): 317db96d56Sopenharmony_ci del self._x_attr[name] 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci @property 347db96d56Sopenharmony_ci def x_exports(self): 357db96d56Sopenharmony_ci """Return the number of times an internal buffer is exported.""" 367db96d56Sopenharmony_ci # Each Xxo instance has a 10-byte buffer that can be 377db96d56Sopenharmony_ci # accessed via the buffer interface (e.g. `memoryview`). 387db96d56Sopenharmony_ci return self._x_exports 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci def demo(o, /): 417db96d56Sopenharmony_ci if isinstance(o, str): 427db96d56Sopenharmony_ci return o 437db96d56Sopenharmony_ci elif isinstance(o, Xxo): 447db96d56Sopenharmony_ci return o 457db96d56Sopenharmony_ci else: 467db96d56Sopenharmony_ci raise Error('argument must be str or Xxo') 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_ci class Error(Exception): 497db96d56Sopenharmony_ci """Exception raised by the xxlimited module""" 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci def foo(i: int, j: int, /): 527db96d56Sopenharmony_ci """Return the sum of i and j.""" 537db96d56Sopenharmony_ci # Unlike this pseudocode, the C function will *only* work with 547db96d56Sopenharmony_ci # integers and perform C long int arithmetic 557db96d56Sopenharmony_ci return i + j 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci def new(): 587db96d56Sopenharmony_ci return Xxo() 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci def Str(str): 617db96d56Sopenharmony_ci # A trivial subclass of a built-in type 627db96d56Sopenharmony_ci pass 637db96d56Sopenharmony_ci */ 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci#define Py_LIMITED_API 0x030b0000 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci#include "Python.h" 687db96d56Sopenharmony_ci#include <string.h> 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci#define BUFSIZE 10 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci// Module state 737db96d56Sopenharmony_citypedef struct { 747db96d56Sopenharmony_ci PyObject *Xxo_Type; // Xxo class 757db96d56Sopenharmony_ci PyObject *Error_Type; // Error class 767db96d56Sopenharmony_ci} xx_state; 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci 797db96d56Sopenharmony_ci/* Xxo objects */ 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci// Instance state 827db96d56Sopenharmony_citypedef struct { 837db96d56Sopenharmony_ci PyObject_HEAD 847db96d56Sopenharmony_ci PyObject *x_attr; /* Attributes dictionary */ 857db96d56Sopenharmony_ci char x_buffer[BUFSIZE]; /* buffer for Py_buffer */ 867db96d56Sopenharmony_ci Py_ssize_t x_exports; /* how many buffer are exported */ 877db96d56Sopenharmony_ci} XxoObject; 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci// XXX: no good way to do this yet 907db96d56Sopenharmony_ci// #define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type) 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_cistatic XxoObject * 937db96d56Sopenharmony_cinewXxoObject(PyObject *module) 947db96d56Sopenharmony_ci{ 957db96d56Sopenharmony_ci xx_state *state = PyModule_GetState(module); 967db96d56Sopenharmony_ci if (state == NULL) { 977db96d56Sopenharmony_ci return NULL; 987db96d56Sopenharmony_ci } 997db96d56Sopenharmony_ci XxoObject *self; 1007db96d56Sopenharmony_ci self = PyObject_GC_New(XxoObject, (PyTypeObject*)state->Xxo_Type); 1017db96d56Sopenharmony_ci if (self == NULL) { 1027db96d56Sopenharmony_ci return NULL; 1037db96d56Sopenharmony_ci } 1047db96d56Sopenharmony_ci self->x_attr = NULL; 1057db96d56Sopenharmony_ci memset(self->x_buffer, 0, BUFSIZE); 1067db96d56Sopenharmony_ci self->x_exports = 0; 1077db96d56Sopenharmony_ci return self; 1087db96d56Sopenharmony_ci} 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci/* Xxo finalization */ 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_cistatic int 1137db96d56Sopenharmony_ciXxo_traverse(PyObject *self_obj, visitproc visit, void *arg) 1147db96d56Sopenharmony_ci{ 1157db96d56Sopenharmony_ci // Visit the type 1167db96d56Sopenharmony_ci Py_VISIT(Py_TYPE(self_obj)); 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci // Visit the attribute dict 1197db96d56Sopenharmony_ci XxoObject *self = (XxoObject *)self_obj; 1207db96d56Sopenharmony_ci Py_VISIT(self->x_attr); 1217db96d56Sopenharmony_ci return 0; 1227db96d56Sopenharmony_ci} 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_cistatic int 1257db96d56Sopenharmony_ciXxo_clear(XxoObject *self) 1267db96d56Sopenharmony_ci{ 1277db96d56Sopenharmony_ci Py_CLEAR(self->x_attr); 1287db96d56Sopenharmony_ci return 0; 1297db96d56Sopenharmony_ci} 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_cistatic void 1327db96d56Sopenharmony_ciXxo_finalize(PyObject *self_obj) 1337db96d56Sopenharmony_ci{ 1347db96d56Sopenharmony_ci XxoObject *self = (XxoObject *)self_obj; 1357db96d56Sopenharmony_ci Py_CLEAR(self->x_attr); 1367db96d56Sopenharmony_ci} 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_cistatic void 1397db96d56Sopenharmony_ciXxo_dealloc(PyObject *self) 1407db96d56Sopenharmony_ci{ 1417db96d56Sopenharmony_ci PyObject_GC_UnTrack(self); 1427db96d56Sopenharmony_ci Xxo_finalize(self); 1437db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(self); 1447db96d56Sopenharmony_ci freefunc free = PyType_GetSlot(tp, Py_tp_free); 1457db96d56Sopenharmony_ci free(self); 1467db96d56Sopenharmony_ci Py_DECREF(tp); 1477db96d56Sopenharmony_ci} 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ci/* Xxo attribute handling */ 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_cistatic PyObject * 1537db96d56Sopenharmony_ciXxo_getattro(XxoObject *self, PyObject *name) 1547db96d56Sopenharmony_ci{ 1557db96d56Sopenharmony_ci if (self->x_attr != NULL) { 1567db96d56Sopenharmony_ci PyObject *v = PyDict_GetItemWithError(self->x_attr, name); 1577db96d56Sopenharmony_ci if (v != NULL) { 1587db96d56Sopenharmony_ci Py_INCREF(v); 1597db96d56Sopenharmony_ci return v; 1607db96d56Sopenharmony_ci } 1617db96d56Sopenharmony_ci else if (PyErr_Occurred()) { 1627db96d56Sopenharmony_ci return NULL; 1637db96d56Sopenharmony_ci } 1647db96d56Sopenharmony_ci } 1657db96d56Sopenharmony_ci return PyObject_GenericGetAttr((PyObject *)self, name); 1667db96d56Sopenharmony_ci} 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_cistatic int 1697db96d56Sopenharmony_ciXxo_setattro(XxoObject *self, PyObject *name, PyObject *v) 1707db96d56Sopenharmony_ci{ 1717db96d56Sopenharmony_ci if (self->x_attr == NULL) { 1727db96d56Sopenharmony_ci // prepare the attribute dict 1737db96d56Sopenharmony_ci self->x_attr = PyDict_New(); 1747db96d56Sopenharmony_ci if (self->x_attr == NULL) { 1757db96d56Sopenharmony_ci return -1; 1767db96d56Sopenharmony_ci } 1777db96d56Sopenharmony_ci } 1787db96d56Sopenharmony_ci if (v == NULL) { 1797db96d56Sopenharmony_ci // delete an attribute 1807db96d56Sopenharmony_ci int rv = PyDict_DelItem(self->x_attr, name); 1817db96d56Sopenharmony_ci if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { 1827db96d56Sopenharmony_ci PyErr_SetString(PyExc_AttributeError, 1837db96d56Sopenharmony_ci "delete non-existing Xxo attribute"); 1847db96d56Sopenharmony_ci return -1; 1857db96d56Sopenharmony_ci } 1867db96d56Sopenharmony_ci return rv; 1877db96d56Sopenharmony_ci } 1887db96d56Sopenharmony_ci else { 1897db96d56Sopenharmony_ci // set an attribute 1907db96d56Sopenharmony_ci return PyDict_SetItem(self->x_attr, name, v); 1917db96d56Sopenharmony_ci } 1927db96d56Sopenharmony_ci} 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci/* Xxo methods */ 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_cistatic PyObject * 1977db96d56Sopenharmony_ciXxo_demo(XxoObject *self, PyTypeObject *defining_class, 1987db96d56Sopenharmony_ci PyObject **args, Py_ssize_t nargs, PyObject *kwnames) 1997db96d56Sopenharmony_ci{ 2007db96d56Sopenharmony_ci if (kwnames != NULL && PyObject_Length(kwnames)) { 2017db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "demo() takes no keyword arguments"); 2027db96d56Sopenharmony_ci return NULL; 2037db96d56Sopenharmony_ci } 2047db96d56Sopenharmony_ci if (nargs != 1) { 2057db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "demo() takes exactly 1 argument"); 2067db96d56Sopenharmony_ci return NULL; 2077db96d56Sopenharmony_ci } 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ci PyObject *o = args[0]; 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci /* Test if the argument is "str" */ 2127db96d56Sopenharmony_ci if (PyUnicode_Check(o)) { 2137db96d56Sopenharmony_ci Py_INCREF(o); 2147db96d56Sopenharmony_ci return o; 2157db96d56Sopenharmony_ci } 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci /* test if the argument is of the Xxo class */ 2187db96d56Sopenharmony_ci if (PyObject_TypeCheck(o, defining_class)) { 2197db96d56Sopenharmony_ci Py_INCREF(o); 2207db96d56Sopenharmony_ci return o; 2217db96d56Sopenharmony_ci } 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci Py_INCREF(Py_None); 2247db96d56Sopenharmony_ci return Py_None; 2257db96d56Sopenharmony_ci} 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_cistatic PyMethodDef Xxo_methods[] = { 2287db96d56Sopenharmony_ci {"demo", _PyCFunction_CAST(Xxo_demo), 2297db96d56Sopenharmony_ci METH_METHOD | METH_FASTCALL | METH_KEYWORDS, PyDoc_STR("demo(o) -> o")}, 2307db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 2317db96d56Sopenharmony_ci}; 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci/* Xxo buffer interface */ 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_cistatic int 2367db96d56Sopenharmony_ciXxo_getbuffer(XxoObject *self, Py_buffer *view, int flags) 2377db96d56Sopenharmony_ci{ 2387db96d56Sopenharmony_ci int res = PyBuffer_FillInfo(view, (PyObject*)self, 2397db96d56Sopenharmony_ci (void *)self->x_buffer, BUFSIZE, 2407db96d56Sopenharmony_ci 0, flags); 2417db96d56Sopenharmony_ci if (res == 0) { 2427db96d56Sopenharmony_ci self->x_exports++; 2437db96d56Sopenharmony_ci } 2447db96d56Sopenharmony_ci return res; 2457db96d56Sopenharmony_ci} 2467db96d56Sopenharmony_ci 2477db96d56Sopenharmony_cistatic void 2487db96d56Sopenharmony_ciXxo_releasebuffer(XxoObject *self, Py_buffer *view) 2497db96d56Sopenharmony_ci{ 2507db96d56Sopenharmony_ci self->x_exports--; 2517db96d56Sopenharmony_ci} 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_cistatic PyObject * 2547db96d56Sopenharmony_ciXxo_get_x_exports(XxoObject *self, void *c) 2557db96d56Sopenharmony_ci{ 2567db96d56Sopenharmony_ci return PyLong_FromSsize_t(self->x_exports); 2577db96d56Sopenharmony_ci} 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci/* Xxo type definition */ 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ciPyDoc_STRVAR(Xxo_doc, 2627db96d56Sopenharmony_ci "A class that explicitly stores attributes in an internal dict"); 2637db96d56Sopenharmony_ci 2647db96d56Sopenharmony_cistatic PyGetSetDef Xxo_getsetlist[] = { 2657db96d56Sopenharmony_ci {"x_exports", (getter) Xxo_get_x_exports, NULL, NULL}, 2667db96d56Sopenharmony_ci {NULL}, 2677db96d56Sopenharmony_ci}; 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci 2707db96d56Sopenharmony_cistatic PyType_Slot Xxo_Type_slots[] = { 2717db96d56Sopenharmony_ci {Py_tp_doc, (char *)Xxo_doc}, 2727db96d56Sopenharmony_ci {Py_tp_traverse, Xxo_traverse}, 2737db96d56Sopenharmony_ci {Py_tp_clear, Xxo_clear}, 2747db96d56Sopenharmony_ci {Py_tp_finalize, Xxo_finalize}, 2757db96d56Sopenharmony_ci {Py_tp_dealloc, Xxo_dealloc}, 2767db96d56Sopenharmony_ci {Py_tp_getattro, Xxo_getattro}, 2777db96d56Sopenharmony_ci {Py_tp_setattro, Xxo_setattro}, 2787db96d56Sopenharmony_ci {Py_tp_methods, Xxo_methods}, 2797db96d56Sopenharmony_ci {Py_bf_getbuffer, Xxo_getbuffer}, 2807db96d56Sopenharmony_ci {Py_bf_releasebuffer, Xxo_releasebuffer}, 2817db96d56Sopenharmony_ci {Py_tp_getset, Xxo_getsetlist}, 2827db96d56Sopenharmony_ci {0, 0}, /* sentinel */ 2837db96d56Sopenharmony_ci}; 2847db96d56Sopenharmony_ci 2857db96d56Sopenharmony_cistatic PyType_Spec Xxo_Type_spec = { 2867db96d56Sopenharmony_ci .name = "xxlimited.Xxo", 2877db96d56Sopenharmony_ci .basicsize = sizeof(XxoObject), 2887db96d56Sopenharmony_ci .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, 2897db96d56Sopenharmony_ci .slots = Xxo_Type_slots, 2907db96d56Sopenharmony_ci}; 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci 2937db96d56Sopenharmony_ci/* Str type definition*/ 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_cistatic PyType_Slot Str_Type_slots[] = { 2967db96d56Sopenharmony_ci {0, 0}, /* sentinel */ 2977db96d56Sopenharmony_ci}; 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_cistatic PyType_Spec Str_Type_spec = { 3007db96d56Sopenharmony_ci .name = "xxlimited.Str", 3017db96d56Sopenharmony_ci .basicsize = 0, 3027db96d56Sopenharmony_ci .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 3037db96d56Sopenharmony_ci .slots = Str_Type_slots, 3047db96d56Sopenharmony_ci}; 3057db96d56Sopenharmony_ci 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ci/* Function of two integers returning integer (with C "long int" arithmetic) */ 3087db96d56Sopenharmony_ci 3097db96d56Sopenharmony_ciPyDoc_STRVAR(xx_foo_doc, 3107db96d56Sopenharmony_ci"foo(i,j)\n\ 3117db96d56Sopenharmony_ci\n\ 3127db96d56Sopenharmony_ciReturn the sum of i and j."); 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_cistatic PyObject * 3157db96d56Sopenharmony_cixx_foo(PyObject *module, PyObject *args) 3167db96d56Sopenharmony_ci{ 3177db96d56Sopenharmony_ci long i, j; 3187db96d56Sopenharmony_ci long res; 3197db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) 3207db96d56Sopenharmony_ci return NULL; 3217db96d56Sopenharmony_ci res = i+j; /* XXX Do something here */ 3227db96d56Sopenharmony_ci return PyLong_FromLong(res); 3237db96d56Sopenharmony_ci} 3247db96d56Sopenharmony_ci 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci/* Function of no arguments returning new Xxo object */ 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_cistatic PyObject * 3297db96d56Sopenharmony_cixx_new(PyObject *module, PyObject *Py_UNUSED(unused)) 3307db96d56Sopenharmony_ci{ 3317db96d56Sopenharmony_ci XxoObject *rv; 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci rv = newXxoObject(module); 3347db96d56Sopenharmony_ci if (rv == NULL) 3357db96d56Sopenharmony_ci return NULL; 3367db96d56Sopenharmony_ci return (PyObject *)rv; 3377db96d56Sopenharmony_ci} 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_ci 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_ci/* List of functions defined in the module */ 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_cistatic PyMethodDef xx_methods[] = { 3447db96d56Sopenharmony_ci {"foo", xx_foo, METH_VARARGS, 3457db96d56Sopenharmony_ci xx_foo_doc}, 3467db96d56Sopenharmony_ci {"new", xx_new, METH_NOARGS, 3477db96d56Sopenharmony_ci PyDoc_STR("new() -> new Xx object")}, 3487db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 3497db96d56Sopenharmony_ci}; 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ci/* The module itself */ 3537db96d56Sopenharmony_ci 3547db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc, 3557db96d56Sopenharmony_ci"This is a template module just for instruction."); 3567db96d56Sopenharmony_ci 3577db96d56Sopenharmony_cistatic int 3587db96d56Sopenharmony_cixx_modexec(PyObject *m) 3597db96d56Sopenharmony_ci{ 3607db96d56Sopenharmony_ci xx_state *state = PyModule_GetState(m); 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ci state->Error_Type = PyErr_NewException("xxlimited.Error", NULL, NULL); 3637db96d56Sopenharmony_ci if (state->Error_Type == NULL) { 3647db96d56Sopenharmony_ci return -1; 3657db96d56Sopenharmony_ci } 3667db96d56Sopenharmony_ci if (PyModule_AddType(m, (PyTypeObject*)state->Error_Type) < 0) { 3677db96d56Sopenharmony_ci return -1; 3687db96d56Sopenharmony_ci } 3697db96d56Sopenharmony_ci 3707db96d56Sopenharmony_ci state->Xxo_Type = PyType_FromModuleAndSpec(m, &Xxo_Type_spec, NULL); 3717db96d56Sopenharmony_ci if (state->Xxo_Type == NULL) { 3727db96d56Sopenharmony_ci return -1; 3737db96d56Sopenharmony_ci } 3747db96d56Sopenharmony_ci if (PyModule_AddType(m, (PyTypeObject*)state->Xxo_Type) < 0) { 3757db96d56Sopenharmony_ci return -1; 3767db96d56Sopenharmony_ci } 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ci // Add the Str type. It is not needed from C code, so it is only 3797db96d56Sopenharmony_ci // added to the module dict. 3807db96d56Sopenharmony_ci // It does not inherit from "object" (PyObject_Type), but from "str" 3817db96d56Sopenharmony_ci // (PyUnincode_Type). 3827db96d56Sopenharmony_ci PyObject *Str_Type = PyType_FromModuleAndSpec( 3837db96d56Sopenharmony_ci m, &Str_Type_spec, (PyObject *)&PyUnicode_Type); 3847db96d56Sopenharmony_ci if (Str_Type == NULL) { 3857db96d56Sopenharmony_ci return -1; 3867db96d56Sopenharmony_ci } 3877db96d56Sopenharmony_ci if (PyModule_AddType(m, (PyTypeObject*)Str_Type) < 0) { 3887db96d56Sopenharmony_ci return -1; 3897db96d56Sopenharmony_ci } 3907db96d56Sopenharmony_ci Py_DECREF(Str_Type); 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_ci return 0; 3937db96d56Sopenharmony_ci} 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_cistatic PyModuleDef_Slot xx_slots[] = { 3967db96d56Sopenharmony_ci {Py_mod_exec, xx_modexec}, 3977db96d56Sopenharmony_ci {0, NULL} 3987db96d56Sopenharmony_ci}; 3997db96d56Sopenharmony_ci 4007db96d56Sopenharmony_cistatic int 4017db96d56Sopenharmony_cixx_traverse(PyObject *module, visitproc visit, void *arg) 4027db96d56Sopenharmony_ci{ 4037db96d56Sopenharmony_ci xx_state *state = PyModule_GetState(module); 4047db96d56Sopenharmony_ci Py_VISIT(state->Xxo_Type); 4057db96d56Sopenharmony_ci Py_VISIT(state->Error_Type); 4067db96d56Sopenharmony_ci return 0; 4077db96d56Sopenharmony_ci} 4087db96d56Sopenharmony_ci 4097db96d56Sopenharmony_cistatic int 4107db96d56Sopenharmony_cixx_clear(PyObject *module) 4117db96d56Sopenharmony_ci{ 4127db96d56Sopenharmony_ci xx_state *state = PyModule_GetState(module); 4137db96d56Sopenharmony_ci Py_CLEAR(state->Xxo_Type); 4147db96d56Sopenharmony_ci Py_CLEAR(state->Error_Type); 4157db96d56Sopenharmony_ci return 0; 4167db96d56Sopenharmony_ci} 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_cistatic struct PyModuleDef xxmodule = { 4197db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 4207db96d56Sopenharmony_ci .m_name = "xxlimited", 4217db96d56Sopenharmony_ci .m_doc = module_doc, 4227db96d56Sopenharmony_ci .m_size = sizeof(xx_state), 4237db96d56Sopenharmony_ci .m_methods = xx_methods, 4247db96d56Sopenharmony_ci .m_slots = xx_slots, 4257db96d56Sopenharmony_ci .m_traverse = xx_traverse, 4267db96d56Sopenharmony_ci .m_clear = xx_clear, 4277db96d56Sopenharmony_ci /* m_free is not necessary here: xx_clear clears all references, 4287db96d56Sopenharmony_ci * and the module state is deallocated along with the module. 4297db96d56Sopenharmony_ci */ 4307db96d56Sopenharmony_ci}; 4317db96d56Sopenharmony_ci 4327db96d56Sopenharmony_ci 4337db96d56Sopenharmony_ci/* Export function for the module (*must* be called PyInit_xx) */ 4347db96d56Sopenharmony_ci 4357db96d56Sopenharmony_ciPyMODINIT_FUNC 4367db96d56Sopenharmony_ciPyInit_xxlimited(void) 4377db96d56Sopenharmony_ci{ 4387db96d56Sopenharmony_ci return PyModuleDef_Init(&xxmodule); 4397db96d56Sopenharmony_ci} 440