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