(root)/
Python-3.12.0/
Modules/
xxmodule.c
       1  
       2  /* Use this file as a template to start implementing a module that
       3     also declares object types. All occurrences of 'Xxo' should be changed
       4     to something reasonable for your objects. After that, all other
       5     occurrences of 'xx' should be changed to something reasonable for your
       6     module. If your module is named foo your sourcefile should be named
       7     foomodule.c.
       8  
       9     You will probably want to delete all references to 'x_attr' and add
      10     your own types of attributes instead.  Maybe you want to name your
      11     local variables other than 'self'.  If your object type is needed in
      12     other files, you'll have to create a file "foobarobject.h"; see
      13     floatobject.h for an example. */
      14  
      15  /* Xxo objects */
      16  
      17  #include "Python.h"
      18  
      19  static PyObject *ErrorObject;
      20  
      21  typedef struct {
      22      PyObject_HEAD
      23      PyObject            *x_attr;        /* Attributes dictionary */
      24  } XxoObject;
      25  
      26  static PyTypeObject Xxo_Type;
      27  
      28  #define XxoObject_Check(v)      Py_IS_TYPE(v, &Xxo_Type)
      29  
      30  static XxoObject *
      31  newXxoObject(PyObject *arg)
      32  {
      33      XxoObject *self;
      34      self = PyObject_New(XxoObject, &Xxo_Type);
      35      if (self == NULL)
      36          return NULL;
      37      self->x_attr = NULL;
      38      return self;
      39  }
      40  
      41  /* Xxo methods */
      42  
      43  static void
      44  Xxo_dealloc(XxoObject *self)
      45  {
      46      Py_XDECREF(self->x_attr);
      47      PyObject_Free(self);
      48  }
      49  
      50  static PyObject *
      51  Xxo_demo(XxoObject *self, PyObject *args)
      52  {
      53      if (!PyArg_ParseTuple(args, ":demo"))
      54          return NULL;
      55      return Py_NewRef(Py_None);
      56  }
      57  
      58  static PyMethodDef Xxo_methods[] = {
      59      {"demo",            (PyCFunction)Xxo_demo,  METH_VARARGS,
      60          PyDoc_STR("demo() -> None")},
      61      {NULL,              NULL}           /* sentinel */
      62  };
      63  
      64  static PyObject *
      65  Xxo_getattro(XxoObject *self, PyObject *name)
      66  {
      67      if (self->x_attr != NULL) {
      68          PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
      69          if (v != NULL) {
      70              return Py_NewRef(v);
      71          }
      72          else if (PyErr_Occurred()) {
      73              return NULL;
      74          }
      75      }
      76      return PyObject_GenericGetAttr((PyObject *)self, name);
      77  }
      78  
      79  static int
      80  Xxo_setattr(XxoObject *self, const char *name, PyObject *v)
      81  {
      82      if (self->x_attr == NULL) {
      83          self->x_attr = PyDict_New();
      84          if (self->x_attr == NULL)
      85              return -1;
      86      }
      87      if (v == NULL) {
      88          int rv = PyDict_DelItemString(self->x_attr, name);
      89          if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
      90              PyErr_SetString(PyExc_AttributeError,
      91                  "delete non-existing Xxo attribute");
      92          return rv;
      93      }
      94      else
      95          return PyDict_SetItemString(self->x_attr, name, v);
      96  }
      97  
      98  static PyTypeObject Xxo_Type = {
      99      /* The ob_type field must be initialized in the module init function
     100       * to be portable to Windows without using C++. */
     101      PyVarObject_HEAD_INIT(NULL, 0)
     102      "xxmodule.Xxo",             /*tp_name*/
     103      sizeof(XxoObject),          /*tp_basicsize*/
     104      0,                          /*tp_itemsize*/
     105      /* methods */
     106      (destructor)Xxo_dealloc,    /*tp_dealloc*/
     107      0,                          /*tp_vectorcall_offset*/
     108      (getattrfunc)0,             /*tp_getattr*/
     109      (setattrfunc)Xxo_setattr,   /*tp_setattr*/
     110      0,                          /*tp_as_async*/
     111      0,                          /*tp_repr*/
     112      0,                          /*tp_as_number*/
     113      0,                          /*tp_as_sequence*/
     114      0,                          /*tp_as_mapping*/
     115      0,                          /*tp_hash*/
     116      0,                          /*tp_call*/
     117      0,                          /*tp_str*/
     118      (getattrofunc)Xxo_getattro, /*tp_getattro*/
     119      0,                          /*tp_setattro*/
     120      0,                          /*tp_as_buffer*/
     121      Py_TPFLAGS_DEFAULT,         /*tp_flags*/
     122      0,                          /*tp_doc*/
     123      0,                          /*tp_traverse*/
     124      0,                          /*tp_clear*/
     125      0,                          /*tp_richcompare*/
     126      0,                          /*tp_weaklistoffset*/
     127      0,                          /*tp_iter*/
     128      0,                          /*tp_iternext*/
     129      Xxo_methods,                /*tp_methods*/
     130      0,                          /*tp_members*/
     131      0,                          /*tp_getset*/
     132      0,                          /*tp_base*/
     133      0,                          /*tp_dict*/
     134      0,                          /*tp_descr_get*/
     135      0,                          /*tp_descr_set*/
     136      0,                          /*tp_dictoffset*/
     137      0,                          /*tp_init*/
     138      0,                          /*tp_alloc*/
     139      0,                          /*tp_new*/
     140      0,                          /*tp_free*/
     141      0,                          /*tp_is_gc*/
     142  };
     143  /* --------------------------------------------------------------------- */
     144  
     145  /* Function of two integers returning integer */
     146  
     147  PyDoc_STRVAR(xx_foo_doc,
     148  "foo(i,j)\n\
     149  \n\
     150  Return the sum of i and j.");
     151  
     152  static PyObject *
     153  xx_foo(PyObject *self, PyObject *args)
     154  {
     155      long i, j;
     156      long res;
     157      if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
     158          return NULL;
     159      res = i+j; /* XXX Do something here */
     160      return PyLong_FromLong(res);
     161  }
     162  
     163  
     164  /* Function of no arguments returning new Xxo object */
     165  
     166  static PyObject *
     167  xx_new(PyObject *self, PyObject *args)
     168  {
     169      XxoObject *rv;
     170  
     171      if (!PyArg_ParseTuple(args, ":new"))
     172          return NULL;
     173      rv = newXxoObject(args);
     174      if (rv == NULL)
     175          return NULL;
     176      return (PyObject *)rv;
     177  }
     178  
     179  /* Example with subtle bug from extensions manual ("Thin Ice"). */
     180  
     181  static PyObject *
     182  xx_bug(PyObject *self, PyObject *args)
     183  {
     184      PyObject *list, *item;
     185  
     186      if (!PyArg_ParseTuple(args, "O:bug", &list))
     187          return NULL;
     188  
     189      item = PyList_GetItem(list, 0);
     190      /* Py_INCREF(item); */
     191      PyList_SetItem(list, 1, PyLong_FromLong(0L));
     192      PyObject_Print(item, stdout, 0);
     193      printf("\n");
     194      /* Py_DECREF(item); */
     195  
     196      return Py_NewRef(Py_None);
     197  }
     198  
     199  /* Test bad format character */
     200  
     201  static PyObject *
     202  xx_roj(PyObject *self, PyObject *args)
     203  {
     204      PyObject *a;
     205      long b;
     206      if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
     207          return NULL;
     208      return Py_NewRef(Py_None);
     209  }
     210  
     211  
     212  /* ---------- */
     213  
     214  static PyTypeObject Str_Type = {
     215      /* The ob_type field must be initialized in the module init function
     216       * to be portable to Windows without using C++. */
     217      PyVarObject_HEAD_INIT(NULL, 0)
     218      "xxmodule.Str",             /*tp_name*/
     219      0,                          /*tp_basicsize*/
     220      0,                          /*tp_itemsize*/
     221      /* methods */
     222      0,                          /*tp_dealloc*/
     223      0,                          /*tp_vectorcall_offset*/
     224      0,                          /*tp_getattr*/
     225      0,                          /*tp_setattr*/
     226      0,                          /*tp_as_async*/
     227      0,                          /*tp_repr*/
     228      0,                          /*tp_as_number*/
     229      0,                          /*tp_as_sequence*/
     230      0,                          /*tp_as_mapping*/
     231      0,                          /*tp_hash*/
     232      0,                          /*tp_call*/
     233      0,                          /*tp_str*/
     234      0,                          /*tp_getattro*/
     235      0,                          /*tp_setattro*/
     236      0,                          /*tp_as_buffer*/
     237      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
     238      0,                          /*tp_doc*/
     239      0,                          /*tp_traverse*/
     240      0,                          /*tp_clear*/
     241      0,                          /*tp_richcompare*/
     242      0,                          /*tp_weaklistoffset*/
     243      0,                          /*tp_iter*/
     244      0,                          /*tp_iternext*/
     245      0,                          /*tp_methods*/
     246      0,                          /*tp_members*/
     247      0,                          /*tp_getset*/
     248      0, /* see PyInit_xx */      /*tp_base*/
     249      0,                          /*tp_dict*/
     250      0,                          /*tp_descr_get*/
     251      0,                          /*tp_descr_set*/
     252      0,                          /*tp_dictoffset*/
     253      0,                          /*tp_init*/
     254      0,                          /*tp_alloc*/
     255      0,                          /*tp_new*/
     256      0,                          /*tp_free*/
     257      0,                          /*tp_is_gc*/
     258  };
     259  
     260  /* ---------- */
     261  
     262  static PyObject *
     263  null_richcompare(PyObject *self, PyObject *other, int op)
     264  {
     265      return Py_NewRef(Py_NotImplemented);
     266  }
     267  
     268  static PyTypeObject Null_Type = {
     269      /* The ob_type field must be initialized in the module init function
     270       * to be portable to Windows without using C++. */
     271      PyVarObject_HEAD_INIT(NULL, 0)
     272      "xxmodule.Null",            /*tp_name*/
     273      0,                          /*tp_basicsize*/
     274      0,                          /*tp_itemsize*/
     275      /* methods */
     276      0,                          /*tp_dealloc*/
     277      0,                          /*tp_vectorcall_offset*/
     278      0,                          /*tp_getattr*/
     279      0,                          /*tp_setattr*/
     280      0,                          /*tp_as_async*/
     281      0,                          /*tp_repr*/
     282      0,                          /*tp_as_number*/
     283      0,                          /*tp_as_sequence*/
     284      0,                          /*tp_as_mapping*/
     285      0,                          /*tp_hash*/
     286      0,                          /*tp_call*/
     287      0,                          /*tp_str*/
     288      0,                          /*tp_getattro*/
     289      0,                          /*tp_setattro*/
     290      0,                          /*tp_as_buffer*/
     291      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
     292      0,                          /*tp_doc*/
     293      0,                          /*tp_traverse*/
     294      0,                          /*tp_clear*/
     295      null_richcompare,           /*tp_richcompare*/
     296      0,                          /*tp_weaklistoffset*/
     297      0,                          /*tp_iter*/
     298      0,                          /*tp_iternext*/
     299      0,                          /*tp_methods*/
     300      0,                          /*tp_members*/
     301      0,                          /*tp_getset*/
     302      0, /* see PyInit_xx */      /*tp_base*/
     303      0,                          /*tp_dict*/
     304      0,                          /*tp_descr_get*/
     305      0,                          /*tp_descr_set*/
     306      0,                          /*tp_dictoffset*/
     307      0,                          /*tp_init*/
     308      0,                          /*tp_alloc*/
     309      PyType_GenericNew,          /*tp_new*/
     310      0,                          /*tp_free*/
     311      0,                          /*tp_is_gc*/
     312  };
     313  
     314  
     315  /* ---------- */
     316  
     317  
     318  /* List of functions defined in the module */
     319  
     320  static PyMethodDef xx_methods[] = {
     321      {"roj",             xx_roj,         METH_VARARGS,
     322          PyDoc_STR("roj(a,b) -> None")},
     323      {"foo",             xx_foo,         METH_VARARGS,
     324          xx_foo_doc},
     325      {"new",             xx_new,         METH_VARARGS,
     326          PyDoc_STR("new() -> new Xx object")},
     327      {"bug",             xx_bug,         METH_VARARGS,
     328          PyDoc_STR("bug(o) -> None")},
     329      {NULL,              NULL}           /* sentinel */
     330  };
     331  
     332  PyDoc_STRVAR(module_doc,
     333  "This is a template module just for instruction.");
     334  
     335  
     336  static int
     337  xx_exec(PyObject *m)
     338  {
     339      /* Slot initialization is subject to the rules of initializing globals.
     340         C99 requires the initializers to be "address constants".  Function
     341         designators like 'PyType_GenericNew', with implicit conversion to
     342         a pointer, are valid C99 address constants.
     343  
     344         However, the unary '&' operator applied to a non-static variable
     345         like 'PyBaseObject_Type' is not required to produce an address
     346         constant.  Compilers may support this (gcc does), MSVC does not.
     347  
     348         Both compilers are strictly standard conforming in this particular
     349         behavior.
     350      */
     351      Null_Type.tp_base = &PyBaseObject_Type;
     352      Str_Type.tp_base = &PyUnicode_Type;
     353  
     354      /* Finalize the type object including setting type of the new type
     355       * object; doing it here is required for portability, too. */
     356      if (PyType_Ready(&Xxo_Type) < 0) {
     357          return -1;
     358      }
     359  
     360      /* Add some symbolic constants to the module */
     361      if (ErrorObject == NULL) {
     362          ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
     363          if (ErrorObject == NULL) {
     364              return -1;
     365          }
     366      }
     367      int rc = PyModule_AddType(m, (PyTypeObject *)ErrorObject);
     368      Py_DECREF(ErrorObject);
     369      if (rc < 0) {
     370          return -1;
     371      }
     372  
     373      /* Add Str and Null types */
     374      if (PyModule_AddType(m, &Str_Type) < 0) {
     375          return -1;
     376      }
     377      if (PyModule_AddType(m, &Null_Type) < 0) {
     378          return -1;
     379      }
     380  
     381      return 0;
     382  }
     383  
     384  static struct PyModuleDef_Slot xx_slots[] = {
     385      {Py_mod_exec, xx_exec},
     386      {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
     387      {0, NULL},
     388  };
     389  
     390  static struct PyModuleDef xxmodule = {
     391      PyModuleDef_HEAD_INIT,
     392      "xx",
     393      module_doc,
     394      0,
     395      xx_methods,
     396      xx_slots,
     397      NULL,
     398      NULL,
     399      NULL
     400  };
     401  
     402  /* Export function for the module (*must* be called PyInit_xx) */
     403  
     404  PyMODINIT_FUNC
     405  PyInit_xx(void)
     406  {
     407      return PyModuleDef_Init(&xxmodule);
     408  }