(root)/
Python-3.11.7/
Modules/
xxlimited_35.c
       1  
       2  /* This module is compiled using limited API from Python 3.5,
       3   * making sure that it works as expected.
       4   *
       5   * See the xxlimited module for an extension module template.
       6   */
       7  
       8  #define Py_LIMITED_API 0x03050000
       9  
      10  #include "Python.h"
      11  
      12  /* Xxo objects */
      13  
      14  static PyObject *ErrorObject;
      15  
      16  typedef struct {
      17      PyObject_HEAD
      18      PyObject            *x_attr;        /* Attributes dictionary */
      19  } XxoObject;
      20  
      21  static PyObject *Xxo_Type;
      22  
      23  #define XxoObject_Check(v)      Py_IS_TYPE(v, Xxo_Type)
      24  
      25  static XxoObject *
      26  newXxoObject(PyObject *arg)
      27  {
      28      XxoObject *self;
      29      self = PyObject_GC_New(XxoObject, (PyTypeObject*)Xxo_Type);
      30      if (self == NULL)
      31          return NULL;
      32      self->x_attr = NULL;
      33      return self;
      34  }
      35  
      36  /* Xxo methods */
      37  
      38  static int
      39  Xxo_traverse(XxoObject *self, visitproc visit, void *arg)
      40  {
      41      Py_VISIT(Py_TYPE(self));
      42      Py_VISIT(self->x_attr);
      43      return 0;
      44  }
      45  
      46  static int
      47  Xxo_clear(XxoObject *self)
      48  {
      49      Py_CLEAR(self->x_attr);
      50      return 0;
      51  }
      52  
      53  static void
      54  Xxo_finalize(XxoObject *self)
      55  {
      56      Py_CLEAR(self->x_attr);
      57  }
      58  
      59  static PyObject *
      60  Xxo_demo(XxoObject *self, PyObject *args)
      61  {
      62      PyObject *o = NULL;
      63      if (!PyArg_ParseTuple(args, "|O:demo", &o))
      64          return NULL;
      65      /* Test availability of fast type checks */
      66      if (o != NULL && PyUnicode_Check(o)) {
      67          Py_INCREF(o);
      68          return o;
      69      }
      70      Py_INCREF(Py_None);
      71      return Py_None;
      72  }
      73  
      74  static PyMethodDef Xxo_methods[] = {
      75      {"demo",            (PyCFunction)Xxo_demo,  METH_VARARGS,
      76          PyDoc_STR("demo() -> None")},
      77      {NULL,              NULL}           /* sentinel */
      78  };
      79  
      80  static PyObject *
      81  Xxo_getattro(XxoObject *self, PyObject *name)
      82  {
      83      if (self->x_attr != NULL) {
      84          PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
      85          if (v != NULL) {
      86              Py_INCREF(v);
      87              return v;
      88          }
      89          else if (PyErr_Occurred()) {
      90              return NULL;
      91          }
      92      }
      93      return PyObject_GenericGetAttr((PyObject *)self, name);
      94  }
      95  
      96  static int
      97  Xxo_setattr(XxoObject *self, const char *name, PyObject *v)
      98  {
      99      if (self->x_attr == NULL) {
     100          self->x_attr = PyDict_New();
     101          if (self->x_attr == NULL)
     102              return -1;
     103      }
     104      if (v == NULL) {
     105          int rv = PyDict_DelItemString(self->x_attr, name);
     106          if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
     107              PyErr_SetString(PyExc_AttributeError,
     108                  "delete non-existing Xxo attribute");
     109          return rv;
     110      }
     111      else
     112          return PyDict_SetItemString(self->x_attr, name, v);
     113  }
     114  
     115  static PyType_Slot Xxo_Type_slots[] = {
     116      {Py_tp_doc, "The Xxo type"},
     117      {Py_tp_traverse, Xxo_traverse},
     118      {Py_tp_clear, Xxo_clear},
     119      {Py_tp_finalize, Xxo_finalize},
     120      {Py_tp_getattro, Xxo_getattro},
     121      {Py_tp_setattr, Xxo_setattr},
     122      {Py_tp_methods, Xxo_methods},
     123      {0, 0},
     124  };
     125  
     126  static PyType_Spec Xxo_Type_spec = {
     127      "xxlimited_35.Xxo",
     128      sizeof(XxoObject),
     129      0,
     130      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
     131      Xxo_Type_slots
     132  };
     133  
     134  /* --------------------------------------------------------------------- */
     135  
     136  /* Function of two integers returning integer */
     137  
     138  PyDoc_STRVAR(xx_foo_doc,
     139  "foo(i,j)\n\
     140  \n\
     141  Return the sum of i and j.");
     142  
     143  static PyObject *
     144  xx_foo(PyObject *self, PyObject *args)
     145  {
     146      long i, j;
     147      long res;
     148      if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
     149          return NULL;
     150      res = i+j; /* XXX Do something here */
     151      return PyLong_FromLong(res);
     152  }
     153  
     154  
     155  /* Function of no arguments returning new Xxo object */
     156  
     157  static PyObject *
     158  xx_new(PyObject *self, PyObject *args)
     159  {
     160      XxoObject *rv;
     161  
     162      if (!PyArg_ParseTuple(args, ":new"))
     163          return NULL;
     164      rv = newXxoObject(args);
     165      if (rv == NULL)
     166          return NULL;
     167      return (PyObject *)rv;
     168  }
     169  
     170  /* Test bad format character */
     171  
     172  static PyObject *
     173  xx_roj(PyObject *self, PyObject *args)
     174  {
     175      PyObject *a;
     176      long b;
     177      if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
     178          return NULL;
     179      Py_INCREF(Py_None);
     180      return Py_None;
     181  }
     182  
     183  
     184  /* ---------- */
     185  
     186  static PyType_Slot Str_Type_slots[] = {
     187      {Py_tp_base, NULL}, /* filled out in module init function */
     188      {0, 0},
     189  };
     190  
     191  static PyType_Spec Str_Type_spec = {
     192      "xxlimited_35.Str",
     193      0,
     194      0,
     195      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     196      Str_Type_slots
     197  };
     198  
     199  /* ---------- */
     200  
     201  static PyObject *
     202  null_richcompare(PyObject *self, PyObject *other, int op)
     203  {
     204      Py_RETURN_NOTIMPLEMENTED;
     205  }
     206  
     207  static PyType_Slot Null_Type_slots[] = {
     208      {Py_tp_base, NULL}, /* filled out in module init */
     209      {Py_tp_new, NULL},
     210      {Py_tp_richcompare, null_richcompare},
     211      {0, 0}
     212  };
     213  
     214  static PyType_Spec Null_Type_spec = {
     215      "xxlimited_35.Null",
     216      0,               /* basicsize */
     217      0,               /* itemsize */
     218      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     219      Null_Type_slots
     220  };
     221  
     222  /* ---------- */
     223  
     224  /* List of functions defined in the module */
     225  
     226  static PyMethodDef xx_methods[] = {
     227      {"roj",             xx_roj,         METH_VARARGS,
     228          PyDoc_STR("roj(a,b) -> None")},
     229      {"foo",             xx_foo,         METH_VARARGS,
     230          xx_foo_doc},
     231      {"new",             xx_new,         METH_VARARGS,
     232          PyDoc_STR("new() -> new Xx object")},
     233      {NULL,              NULL}           /* sentinel */
     234  };
     235  
     236  PyDoc_STRVAR(module_doc,
     237  "This is a module for testing limited API from Python 3.5.");
     238  
     239  static int
     240  xx_modexec(PyObject *m)
     241  {
     242      PyObject *o;
     243  
     244      /* Due to cross platform compiler issues the slots must be filled
     245       * here. It's required for portability to Windows without requiring
     246       * C++. */
     247      Null_Type_slots[0].pfunc = &PyBaseObject_Type;
     248      Null_Type_slots[1].pfunc = PyType_GenericNew;
     249      Str_Type_slots[0].pfunc = &PyUnicode_Type;
     250  
     251      /* Add some symbolic constants to the module */
     252      if (ErrorObject == NULL) {
     253          ErrorObject = PyErr_NewException("xxlimited_35.error", NULL, NULL);
     254          if (ErrorObject == NULL) {
     255              return -1;
     256          }
     257      }
     258      Py_INCREF(ErrorObject);
     259      if (PyModule_AddObject(m, "error", ErrorObject) < 0) {
     260          Py_DECREF(ErrorObject);
     261          return -1;
     262      }
     263  
     264      /* Add Xxo */
     265      Xxo_Type = PyType_FromSpec(&Xxo_Type_spec);
     266      if (Xxo_Type == NULL) {
     267          return -1;
     268      }
     269      if (PyModule_AddObject(m, "Xxo", Xxo_Type) < 0) {
     270          Py_DECREF(Xxo_Type);
     271          return -1;
     272      }
     273  
     274      /* Add Str */
     275      o = PyType_FromSpec(&Str_Type_spec);
     276      if (o == NULL) {
     277          return -1;
     278      }
     279      if (PyModule_AddObject(m, "Str", o) < 0) {
     280          Py_DECREF(o);
     281          return -1;
     282      }
     283  
     284      /* Add Null */
     285      o = PyType_FromSpec(&Null_Type_spec);
     286      if (o == NULL) {
     287          return -1;
     288      }
     289      if (PyModule_AddObject(m, "Null", o) < 0) {
     290          Py_DECREF(o);
     291          return -1;
     292      }
     293  
     294      return 0;
     295  }
     296  
     297  
     298  static PyModuleDef_Slot xx_slots[] = {
     299      {Py_mod_exec, xx_modexec},
     300      {0, NULL}
     301  };
     302  
     303  static struct PyModuleDef xxmodule = {
     304      PyModuleDef_HEAD_INIT,
     305      "xxlimited_35",
     306      module_doc,
     307      0,
     308      xx_methods,
     309      xx_slots,
     310      NULL,
     311      NULL,
     312      NULL
     313  };
     314  
     315  /* Export function for the module (*must* be called PyInit_xx) */
     316  
     317  PyMODINIT_FUNC
     318  PyInit_xxlimited_35(void)
     319  {
     320      return PyModuleDef_Init(&xxmodule);
     321  }