17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci/* Use this file as a template to start implementing a module that
37db96d56Sopenharmony_ci   also declares object types. All occurrences of 'Xxo' should be changed
47db96d56Sopenharmony_ci   to something reasonable for your objects. After that, all other
57db96d56Sopenharmony_ci   occurrences of 'xx' should be changed to something reasonable for your
67db96d56Sopenharmony_ci   module. If your module is named foo your sourcefile should be named
77db96d56Sopenharmony_ci   foomodule.c.
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci   You will probably want to delete all references to 'x_attr' and add
107db96d56Sopenharmony_ci   your own types of attributes instead.  Maybe you want to name your
117db96d56Sopenharmony_ci   local variables other than 'self'.  If your object type is needed in
127db96d56Sopenharmony_ci   other files, you'll have to create a file "foobarobject.h"; see
137db96d56Sopenharmony_ci   floatobject.h for an example. */
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci/* Xxo objects */
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci#include "Python.h"
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_cistatic PyObject *ErrorObject;
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_citypedef struct {
227db96d56Sopenharmony_ci    PyObject_HEAD
237db96d56Sopenharmony_ci    PyObject            *x_attr;        /* Attributes dictionary */
247db96d56Sopenharmony_ci} XxoObject;
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_cistatic PyTypeObject Xxo_Type;
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci#define XxoObject_Check(v)      Py_IS_TYPE(v, &Xxo_Type)
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_cistatic XxoObject *
317db96d56Sopenharmony_cinewXxoObject(PyObject *arg)
327db96d56Sopenharmony_ci{
337db96d56Sopenharmony_ci    XxoObject *self;
347db96d56Sopenharmony_ci    self = PyObject_New(XxoObject, &Xxo_Type);
357db96d56Sopenharmony_ci    if (self == NULL)
367db96d56Sopenharmony_ci        return NULL;
377db96d56Sopenharmony_ci    self->x_attr = NULL;
387db96d56Sopenharmony_ci    return self;
397db96d56Sopenharmony_ci}
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci/* Xxo methods */
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_cistatic void
447db96d56Sopenharmony_ciXxo_dealloc(XxoObject *self)
457db96d56Sopenharmony_ci{
467db96d56Sopenharmony_ci    Py_XDECREF(self->x_attr);
477db96d56Sopenharmony_ci    PyObject_Free(self);
487db96d56Sopenharmony_ci}
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_cistatic PyObject *
517db96d56Sopenharmony_ciXxo_demo(XxoObject *self, PyObject *args)
527db96d56Sopenharmony_ci{
537db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, ":demo"))
547db96d56Sopenharmony_ci        return NULL;
557db96d56Sopenharmony_ci    Py_INCREF(Py_None);
567db96d56Sopenharmony_ci    return Py_None;
577db96d56Sopenharmony_ci}
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_cistatic PyMethodDef Xxo_methods[] = {
607db96d56Sopenharmony_ci    {"demo",            (PyCFunction)Xxo_demo,  METH_VARARGS,
617db96d56Sopenharmony_ci        PyDoc_STR("demo() -> None")},
627db96d56Sopenharmony_ci    {NULL,              NULL}           /* sentinel */
637db96d56Sopenharmony_ci};
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_cistatic PyObject *
667db96d56Sopenharmony_ciXxo_getattro(XxoObject *self, PyObject *name)
677db96d56Sopenharmony_ci{
687db96d56Sopenharmony_ci    if (self->x_attr != NULL) {
697db96d56Sopenharmony_ci        PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
707db96d56Sopenharmony_ci        if (v != NULL) {
717db96d56Sopenharmony_ci            Py_INCREF(v);
727db96d56Sopenharmony_ci            return v;
737db96d56Sopenharmony_ci        }
747db96d56Sopenharmony_ci        else if (PyErr_Occurred()) {
757db96d56Sopenharmony_ci            return NULL;
767db96d56Sopenharmony_ci        }
777db96d56Sopenharmony_ci    }
787db96d56Sopenharmony_ci    return PyObject_GenericGetAttr((PyObject *)self, name);
797db96d56Sopenharmony_ci}
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_cistatic int
827db96d56Sopenharmony_ciXxo_setattr(XxoObject *self, const char *name, PyObject *v)
837db96d56Sopenharmony_ci{
847db96d56Sopenharmony_ci    if (self->x_attr == NULL) {
857db96d56Sopenharmony_ci        self->x_attr = PyDict_New();
867db96d56Sopenharmony_ci        if (self->x_attr == NULL)
877db96d56Sopenharmony_ci            return -1;
887db96d56Sopenharmony_ci    }
897db96d56Sopenharmony_ci    if (v == NULL) {
907db96d56Sopenharmony_ci        int rv = PyDict_DelItemString(self->x_attr, name);
917db96d56Sopenharmony_ci        if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
927db96d56Sopenharmony_ci            PyErr_SetString(PyExc_AttributeError,
937db96d56Sopenharmony_ci                "delete non-existing Xxo attribute");
947db96d56Sopenharmony_ci        return rv;
957db96d56Sopenharmony_ci    }
967db96d56Sopenharmony_ci    else
977db96d56Sopenharmony_ci        return PyDict_SetItemString(self->x_attr, name, v);
987db96d56Sopenharmony_ci}
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_cistatic PyTypeObject Xxo_Type = {
1017db96d56Sopenharmony_ci    /* The ob_type field must be initialized in the module init function
1027db96d56Sopenharmony_ci     * to be portable to Windows without using C++. */
1037db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
1047db96d56Sopenharmony_ci    "xxmodule.Xxo",             /*tp_name*/
1057db96d56Sopenharmony_ci    sizeof(XxoObject),          /*tp_basicsize*/
1067db96d56Sopenharmony_ci    0,                          /*tp_itemsize*/
1077db96d56Sopenharmony_ci    /* methods */
1087db96d56Sopenharmony_ci    (destructor)Xxo_dealloc,    /*tp_dealloc*/
1097db96d56Sopenharmony_ci    0,                          /*tp_vectorcall_offset*/
1107db96d56Sopenharmony_ci    (getattrfunc)0,             /*tp_getattr*/
1117db96d56Sopenharmony_ci    (setattrfunc)Xxo_setattr,   /*tp_setattr*/
1127db96d56Sopenharmony_ci    0,                          /*tp_as_async*/
1137db96d56Sopenharmony_ci    0,                          /*tp_repr*/
1147db96d56Sopenharmony_ci    0,                          /*tp_as_number*/
1157db96d56Sopenharmony_ci    0,                          /*tp_as_sequence*/
1167db96d56Sopenharmony_ci    0,                          /*tp_as_mapping*/
1177db96d56Sopenharmony_ci    0,                          /*tp_hash*/
1187db96d56Sopenharmony_ci    0,                          /*tp_call*/
1197db96d56Sopenharmony_ci    0,                          /*tp_str*/
1207db96d56Sopenharmony_ci    (getattrofunc)Xxo_getattro, /*tp_getattro*/
1217db96d56Sopenharmony_ci    0,                          /*tp_setattro*/
1227db96d56Sopenharmony_ci    0,                          /*tp_as_buffer*/
1237db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT,         /*tp_flags*/
1247db96d56Sopenharmony_ci    0,                          /*tp_doc*/
1257db96d56Sopenharmony_ci    0,                          /*tp_traverse*/
1267db96d56Sopenharmony_ci    0,                          /*tp_clear*/
1277db96d56Sopenharmony_ci    0,                          /*tp_richcompare*/
1287db96d56Sopenharmony_ci    0,                          /*tp_weaklistoffset*/
1297db96d56Sopenharmony_ci    0,                          /*tp_iter*/
1307db96d56Sopenharmony_ci    0,                          /*tp_iternext*/
1317db96d56Sopenharmony_ci    Xxo_methods,                /*tp_methods*/
1327db96d56Sopenharmony_ci    0,                          /*tp_members*/
1337db96d56Sopenharmony_ci    0,                          /*tp_getset*/
1347db96d56Sopenharmony_ci    0,                          /*tp_base*/
1357db96d56Sopenharmony_ci    0,                          /*tp_dict*/
1367db96d56Sopenharmony_ci    0,                          /*tp_descr_get*/
1377db96d56Sopenharmony_ci    0,                          /*tp_descr_set*/
1387db96d56Sopenharmony_ci    0,                          /*tp_dictoffset*/
1397db96d56Sopenharmony_ci    0,                          /*tp_init*/
1407db96d56Sopenharmony_ci    0,                          /*tp_alloc*/
1417db96d56Sopenharmony_ci    0,                          /*tp_new*/
1427db96d56Sopenharmony_ci    0,                          /*tp_free*/
1437db96d56Sopenharmony_ci    0,                          /*tp_is_gc*/
1447db96d56Sopenharmony_ci};
1457db96d56Sopenharmony_ci/* --------------------------------------------------------------------- */
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci/* Function of two integers returning integer */
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ciPyDoc_STRVAR(xx_foo_doc,
1507db96d56Sopenharmony_ci"foo(i,j)\n\
1517db96d56Sopenharmony_ci\n\
1527db96d56Sopenharmony_ciReturn the sum of i and j.");
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_cistatic PyObject *
1557db96d56Sopenharmony_cixx_foo(PyObject *self, PyObject *args)
1567db96d56Sopenharmony_ci{
1577db96d56Sopenharmony_ci    long i, j;
1587db96d56Sopenharmony_ci    long res;
1597db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
1607db96d56Sopenharmony_ci        return NULL;
1617db96d56Sopenharmony_ci    res = i+j; /* XXX Do something here */
1627db96d56Sopenharmony_ci    return PyLong_FromLong(res);
1637db96d56Sopenharmony_ci}
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ci/* Function of no arguments returning new Xxo object */
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_cistatic PyObject *
1697db96d56Sopenharmony_cixx_new(PyObject *self, PyObject *args)
1707db96d56Sopenharmony_ci{
1717db96d56Sopenharmony_ci    XxoObject *rv;
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, ":new"))
1747db96d56Sopenharmony_ci        return NULL;
1757db96d56Sopenharmony_ci    rv = newXxoObject(args);
1767db96d56Sopenharmony_ci    if (rv == NULL)
1777db96d56Sopenharmony_ci        return NULL;
1787db96d56Sopenharmony_ci    return (PyObject *)rv;
1797db96d56Sopenharmony_ci}
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ci/* Example with subtle bug from extensions manual ("Thin Ice"). */
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_cistatic PyObject *
1847db96d56Sopenharmony_cixx_bug(PyObject *self, PyObject *args)
1857db96d56Sopenharmony_ci{
1867db96d56Sopenharmony_ci    PyObject *list, *item;
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, "O:bug", &list))
1897db96d56Sopenharmony_ci        return NULL;
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci    item = PyList_GetItem(list, 0);
1927db96d56Sopenharmony_ci    /* Py_INCREF(item); */
1937db96d56Sopenharmony_ci    PyList_SetItem(list, 1, PyLong_FromLong(0L));
1947db96d56Sopenharmony_ci    PyObject_Print(item, stdout, 0);
1957db96d56Sopenharmony_ci    printf("\n");
1967db96d56Sopenharmony_ci    /* Py_DECREF(item); */
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci    Py_INCREF(Py_None);
1997db96d56Sopenharmony_ci    return Py_None;
2007db96d56Sopenharmony_ci}
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci/* Test bad format character */
2037db96d56Sopenharmony_ci
2047db96d56Sopenharmony_cistatic PyObject *
2057db96d56Sopenharmony_cixx_roj(PyObject *self, PyObject *args)
2067db96d56Sopenharmony_ci{
2077db96d56Sopenharmony_ci    PyObject *a;
2087db96d56Sopenharmony_ci    long b;
2097db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
2107db96d56Sopenharmony_ci        return NULL;
2117db96d56Sopenharmony_ci    Py_INCREF(Py_None);
2127db96d56Sopenharmony_ci    return Py_None;
2137db96d56Sopenharmony_ci}
2147db96d56Sopenharmony_ci
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ci/* ---------- */
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_cistatic PyTypeObject Str_Type = {
2197db96d56Sopenharmony_ci    /* The ob_type field must be initialized in the module init function
2207db96d56Sopenharmony_ci     * to be portable to Windows without using C++. */
2217db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
2227db96d56Sopenharmony_ci    "xxmodule.Str",             /*tp_name*/
2237db96d56Sopenharmony_ci    0,                          /*tp_basicsize*/
2247db96d56Sopenharmony_ci    0,                          /*tp_itemsize*/
2257db96d56Sopenharmony_ci    /* methods */
2267db96d56Sopenharmony_ci    0,                          /*tp_dealloc*/
2277db96d56Sopenharmony_ci    0,                          /*tp_vectorcall_offset*/
2287db96d56Sopenharmony_ci    0,                          /*tp_getattr*/
2297db96d56Sopenharmony_ci    0,                          /*tp_setattr*/
2307db96d56Sopenharmony_ci    0,                          /*tp_as_async*/
2317db96d56Sopenharmony_ci    0,                          /*tp_repr*/
2327db96d56Sopenharmony_ci    0,                          /*tp_as_number*/
2337db96d56Sopenharmony_ci    0,                          /*tp_as_sequence*/
2347db96d56Sopenharmony_ci    0,                          /*tp_as_mapping*/
2357db96d56Sopenharmony_ci    0,                          /*tp_hash*/
2367db96d56Sopenharmony_ci    0,                          /*tp_call*/
2377db96d56Sopenharmony_ci    0,                          /*tp_str*/
2387db96d56Sopenharmony_ci    0,                          /*tp_getattro*/
2397db96d56Sopenharmony_ci    0,                          /*tp_setattro*/
2407db96d56Sopenharmony_ci    0,                          /*tp_as_buffer*/
2417db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
2427db96d56Sopenharmony_ci    0,                          /*tp_doc*/
2437db96d56Sopenharmony_ci    0,                          /*tp_traverse*/
2447db96d56Sopenharmony_ci    0,                          /*tp_clear*/
2457db96d56Sopenharmony_ci    0,                          /*tp_richcompare*/
2467db96d56Sopenharmony_ci    0,                          /*tp_weaklistoffset*/
2477db96d56Sopenharmony_ci    0,                          /*tp_iter*/
2487db96d56Sopenharmony_ci    0,                          /*tp_iternext*/
2497db96d56Sopenharmony_ci    0,                          /*tp_methods*/
2507db96d56Sopenharmony_ci    0,                          /*tp_members*/
2517db96d56Sopenharmony_ci    0,                          /*tp_getset*/
2527db96d56Sopenharmony_ci    0, /* see PyInit_xx */      /*tp_base*/
2537db96d56Sopenharmony_ci    0,                          /*tp_dict*/
2547db96d56Sopenharmony_ci    0,                          /*tp_descr_get*/
2557db96d56Sopenharmony_ci    0,                          /*tp_descr_set*/
2567db96d56Sopenharmony_ci    0,                          /*tp_dictoffset*/
2577db96d56Sopenharmony_ci    0,                          /*tp_init*/
2587db96d56Sopenharmony_ci    0,                          /*tp_alloc*/
2597db96d56Sopenharmony_ci    0,                          /*tp_new*/
2607db96d56Sopenharmony_ci    0,                          /*tp_free*/
2617db96d56Sopenharmony_ci    0,                          /*tp_is_gc*/
2627db96d56Sopenharmony_ci};
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci/* ---------- */
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_cistatic PyObject *
2677db96d56Sopenharmony_cinull_richcompare(PyObject *self, PyObject *other, int op)
2687db96d56Sopenharmony_ci{
2697db96d56Sopenharmony_ci    Py_INCREF(Py_NotImplemented);
2707db96d56Sopenharmony_ci    return Py_NotImplemented;
2717db96d56Sopenharmony_ci}
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_cistatic PyTypeObject Null_Type = {
2747db96d56Sopenharmony_ci    /* The ob_type field must be initialized in the module init function
2757db96d56Sopenharmony_ci     * to be portable to Windows without using C++. */
2767db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
2777db96d56Sopenharmony_ci    "xxmodule.Null",            /*tp_name*/
2787db96d56Sopenharmony_ci    0,                          /*tp_basicsize*/
2797db96d56Sopenharmony_ci    0,                          /*tp_itemsize*/
2807db96d56Sopenharmony_ci    /* methods */
2817db96d56Sopenharmony_ci    0,                          /*tp_dealloc*/
2827db96d56Sopenharmony_ci    0,                          /*tp_vectorcall_offset*/
2837db96d56Sopenharmony_ci    0,                          /*tp_getattr*/
2847db96d56Sopenharmony_ci    0,                          /*tp_setattr*/
2857db96d56Sopenharmony_ci    0,                          /*tp_as_async*/
2867db96d56Sopenharmony_ci    0,                          /*tp_repr*/
2877db96d56Sopenharmony_ci    0,                          /*tp_as_number*/
2887db96d56Sopenharmony_ci    0,                          /*tp_as_sequence*/
2897db96d56Sopenharmony_ci    0,                          /*tp_as_mapping*/
2907db96d56Sopenharmony_ci    0,                          /*tp_hash*/
2917db96d56Sopenharmony_ci    0,                          /*tp_call*/
2927db96d56Sopenharmony_ci    0,                          /*tp_str*/
2937db96d56Sopenharmony_ci    0,                          /*tp_getattro*/
2947db96d56Sopenharmony_ci    0,                          /*tp_setattro*/
2957db96d56Sopenharmony_ci    0,                          /*tp_as_buffer*/
2967db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
2977db96d56Sopenharmony_ci    0,                          /*tp_doc*/
2987db96d56Sopenharmony_ci    0,                          /*tp_traverse*/
2997db96d56Sopenharmony_ci    0,                          /*tp_clear*/
3007db96d56Sopenharmony_ci    null_richcompare,           /*tp_richcompare*/
3017db96d56Sopenharmony_ci    0,                          /*tp_weaklistoffset*/
3027db96d56Sopenharmony_ci    0,                          /*tp_iter*/
3037db96d56Sopenharmony_ci    0,                          /*tp_iternext*/
3047db96d56Sopenharmony_ci    0,                          /*tp_methods*/
3057db96d56Sopenharmony_ci    0,                          /*tp_members*/
3067db96d56Sopenharmony_ci    0,                          /*tp_getset*/
3077db96d56Sopenharmony_ci    0, /* see PyInit_xx */      /*tp_base*/
3087db96d56Sopenharmony_ci    0,                          /*tp_dict*/
3097db96d56Sopenharmony_ci    0,                          /*tp_descr_get*/
3107db96d56Sopenharmony_ci    0,                          /*tp_descr_set*/
3117db96d56Sopenharmony_ci    0,                          /*tp_dictoffset*/
3127db96d56Sopenharmony_ci    0,                          /*tp_init*/
3137db96d56Sopenharmony_ci    0,                          /*tp_alloc*/
3147db96d56Sopenharmony_ci    PyType_GenericNew,          /*tp_new*/
3157db96d56Sopenharmony_ci    0,                          /*tp_free*/
3167db96d56Sopenharmony_ci    0,                          /*tp_is_gc*/
3177db96d56Sopenharmony_ci};
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ci
3207db96d56Sopenharmony_ci/* ---------- */
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci
3237db96d56Sopenharmony_ci/* List of functions defined in the module */
3247db96d56Sopenharmony_ci
3257db96d56Sopenharmony_cistatic PyMethodDef xx_methods[] = {
3267db96d56Sopenharmony_ci    {"roj",             xx_roj,         METH_VARARGS,
3277db96d56Sopenharmony_ci        PyDoc_STR("roj(a,b) -> None")},
3287db96d56Sopenharmony_ci    {"foo",             xx_foo,         METH_VARARGS,
3297db96d56Sopenharmony_ci        xx_foo_doc},
3307db96d56Sopenharmony_ci    {"new",             xx_new,         METH_VARARGS,
3317db96d56Sopenharmony_ci        PyDoc_STR("new() -> new Xx object")},
3327db96d56Sopenharmony_ci    {"bug",             xx_bug,         METH_VARARGS,
3337db96d56Sopenharmony_ci        PyDoc_STR("bug(o) -> None")},
3347db96d56Sopenharmony_ci    {NULL,              NULL}           /* sentinel */
3357db96d56Sopenharmony_ci};
3367db96d56Sopenharmony_ci
3377db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc,
3387db96d56Sopenharmony_ci"This is a template module just for instruction.");
3397db96d56Sopenharmony_ci
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_cistatic int
3427db96d56Sopenharmony_cixx_exec(PyObject *m)
3437db96d56Sopenharmony_ci{
3447db96d56Sopenharmony_ci    /* Slot initialization is subject to the rules of initializing globals.
3457db96d56Sopenharmony_ci       C99 requires the initializers to be "address constants".  Function
3467db96d56Sopenharmony_ci       designators like 'PyType_GenericNew', with implicit conversion to
3477db96d56Sopenharmony_ci       a pointer, are valid C99 address constants.
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_ci       However, the unary '&' operator applied to a non-static variable
3507db96d56Sopenharmony_ci       like 'PyBaseObject_Type' is not required to produce an address
3517db96d56Sopenharmony_ci       constant.  Compilers may support this (gcc does), MSVC does not.
3527db96d56Sopenharmony_ci
3537db96d56Sopenharmony_ci       Both compilers are strictly standard conforming in this particular
3547db96d56Sopenharmony_ci       behavior.
3557db96d56Sopenharmony_ci    */
3567db96d56Sopenharmony_ci    Null_Type.tp_base = &PyBaseObject_Type;
3577db96d56Sopenharmony_ci    Str_Type.tp_base = &PyUnicode_Type;
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci    /* Finalize the type object including setting type of the new type
3607db96d56Sopenharmony_ci     * object; doing it here is required for portability, too. */
3617db96d56Sopenharmony_ci    if (PyType_Ready(&Xxo_Type) < 0) {
3627db96d56Sopenharmony_ci        return -1;
3637db96d56Sopenharmony_ci    }
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci    /* Add some symbolic constants to the module */
3667db96d56Sopenharmony_ci    if (ErrorObject == NULL) {
3677db96d56Sopenharmony_ci        ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
3687db96d56Sopenharmony_ci        if (ErrorObject == NULL) {
3697db96d56Sopenharmony_ci            return -1;
3707db96d56Sopenharmony_ci        }
3717db96d56Sopenharmony_ci    }
3727db96d56Sopenharmony_ci    int rc = PyModule_AddType(m, (PyTypeObject *)ErrorObject);
3737db96d56Sopenharmony_ci    Py_DECREF(ErrorObject);
3747db96d56Sopenharmony_ci    if (rc < 0) {
3757db96d56Sopenharmony_ci        return -1;
3767db96d56Sopenharmony_ci    }
3777db96d56Sopenharmony_ci
3787db96d56Sopenharmony_ci    /* Add Str and Null types */
3797db96d56Sopenharmony_ci    if (PyModule_AddType(m, &Str_Type) < 0) {
3807db96d56Sopenharmony_ci        return -1;
3817db96d56Sopenharmony_ci    }
3827db96d56Sopenharmony_ci    if (PyModule_AddType(m, &Null_Type) < 0) {
3837db96d56Sopenharmony_ci        return -1;
3847db96d56Sopenharmony_ci    }
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ci    return 0;
3877db96d56Sopenharmony_ci}
3887db96d56Sopenharmony_ci
3897db96d56Sopenharmony_cistatic struct PyModuleDef_Slot xx_slots[] = {
3907db96d56Sopenharmony_ci    {Py_mod_exec, xx_exec},
3917db96d56Sopenharmony_ci    {0, NULL},
3927db96d56Sopenharmony_ci};
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_cistatic struct PyModuleDef xxmodule = {
3957db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
3967db96d56Sopenharmony_ci    "xx",
3977db96d56Sopenharmony_ci    module_doc,
3987db96d56Sopenharmony_ci    0,
3997db96d56Sopenharmony_ci    xx_methods,
4007db96d56Sopenharmony_ci    xx_slots,
4017db96d56Sopenharmony_ci    NULL,
4027db96d56Sopenharmony_ci    NULL,
4037db96d56Sopenharmony_ci    NULL
4047db96d56Sopenharmony_ci};
4057db96d56Sopenharmony_ci
4067db96d56Sopenharmony_ci/* Export function for the module (*must* be called PyInit_xx) */
4077db96d56Sopenharmony_ci
4087db96d56Sopenharmony_ciPyMODINIT_FUNC
4097db96d56Sopenharmony_ciPyInit_xx(void)
4107db96d56Sopenharmony_ci{
4117db96d56Sopenharmony_ci    return PyModuleDef_Init(&xxmodule);
4127db96d56Sopenharmony_ci}
413