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