(root)/
Python-3.12.0/
Modules/
_testcapi/
exceptions.c
       1  #define PY_SSIZE_T_CLEAN
       2  #include "parts.h"
       3  #include "util.h"
       4  #include "clinic/exceptions.c.h"
       5  
       6  
       7  /*[clinic input]
       8  module _testcapi
       9  [clinic start generated code]*/
      10  /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/
      11  
      12  /*[clinic input]
      13  _testcapi.err_set_raised
      14      exception as exc: object
      15      /
      16  [clinic start generated code]*/
      17  
      18  static PyObject *
      19  _testcapi_err_set_raised(PyObject *module, PyObject *exc)
      20  /*[clinic end generated code: output=0a0c7743961fcae5 input=c5f7331864a94df9]*/
      21  {
      22      Py_INCREF(exc);
      23      PyErr_SetRaisedException(exc);
      24      assert(PyErr_Occurred());
      25      return NULL;
      26  }
      27  
      28  static PyObject *
      29  err_restore(PyObject *self, PyObject *args) {
      30      PyObject *type = NULL, *value = NULL, *traceback = NULL;
      31      switch(PyTuple_Size(args)) {
      32          case 3:
      33              traceback = PyTuple_GetItem(args, 2);
      34              Py_INCREF(traceback);
      35              /* fall through */
      36          case 2:
      37              value = PyTuple_GetItem(args, 1);
      38              Py_INCREF(value);
      39              /* fall through */
      40          case 1:
      41              type = PyTuple_GetItem(args, 0);
      42              Py_INCREF(type);
      43              break;
      44          default:
      45              PyErr_SetString(PyExc_TypeError,
      46                          "wrong number of arguments");
      47              return NULL;
      48      }
      49      PyErr_Restore(type, value, traceback);
      50      assert(PyErr_Occurred());
      51      return NULL;
      52  }
      53  
      54  /*[clinic input]
      55  _testcapi.exception_print
      56      exception as exc: object
      57      legacy: bool = False
      58      /
      59  
      60  To test the format of exceptions as printed out.
      61  [clinic start generated code]*/
      62  
      63  static PyObject *
      64  _testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy)
      65  /*[clinic end generated code: output=3f04fe0c18412ae0 input=c76f42cb94136dbf]*/
      66  {
      67      if (legacy) {
      68          PyObject *tb = NULL;
      69          if (PyExceptionInstance_Check(exc)) {
      70              tb = PyException_GetTraceback(exc);
      71          }
      72          PyErr_Display((PyObject *) Py_TYPE(exc), exc, tb);
      73          Py_XDECREF(tb);
      74      }
      75      else {
      76          PyErr_DisplayException(exc);
      77      }
      78      Py_RETURN_NONE;
      79  }
      80  
      81  /*[clinic input]
      82  _testcapi.make_exception_with_doc
      83      name: str
      84      doc: str = NULL
      85      base: object = NULL
      86      dict: object = NULL
      87  
      88  Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py
      89  [clinic start generated code]*/
      90  
      91  static PyObject *
      92  _testcapi_make_exception_with_doc_impl(PyObject *module, const char *name,
      93                                         const char *doc, PyObject *base,
      94                                         PyObject *dict)
      95  /*[clinic end generated code: output=439f0d963c1ce2c4 input=23a73013f8a8795a]*/
      96  {
      97      return PyErr_NewExceptionWithDoc(name, doc, base, dict);
      98  }
      99  
     100  /*[clinic input]
     101  _testcapi.exc_set_object
     102      exception as exc: object
     103      obj: object
     104      /
     105  [clinic start generated code]*/
     106  
     107  static PyObject *
     108  _testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj)
     109  /*[clinic end generated code: output=34c8c7c83e5c8463 input=fc530aafb1b0a360]*/
     110  {
     111      PyErr_SetObject(exc, obj);
     112      return NULL;
     113  }
     114  
     115  /*[clinic input]
     116  _testcapi.exc_set_object_fetch = _testcapi.exc_set_object
     117  [clinic start generated code]*/
     118  
     119  static PyObject *
     120  _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc,
     121                                      PyObject *obj)
     122  /*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/
     123  {
     124      PyObject *type = UNINITIALIZED_PTR;
     125      PyObject *value = UNINITIALIZED_PTR;
     126      PyObject *tb = UNINITIALIZED_PTR;
     127  
     128      PyErr_SetObject(exc, obj);
     129      PyErr_Fetch(&type, &value, &tb);
     130      assert(type != UNINITIALIZED_PTR);
     131      assert(value != UNINITIALIZED_PTR);
     132      assert(tb != UNINITIALIZED_PTR);
     133      Py_XDECREF(type);
     134      Py_XDECREF(tb);
     135      return value;
     136  }
     137  
     138  /*[clinic input]
     139  _testcapi.err_setstring
     140      exc: object
     141      value: str(zeroes=True, accept={robuffer, str, NoneType})
     142      /
     143  [clinic start generated code]*/
     144  
     145  static PyObject *
     146  _testcapi_err_setstring_impl(PyObject *module, PyObject *exc,
     147                               const char *value, Py_ssize_t value_length)
     148  /*[clinic end generated code: output=fba8705e5703dd3f input=e8a95fad66d9004b]*/
     149  {
     150      NULLABLE(exc);
     151      PyErr_SetString(exc, value);
     152      return NULL;
     153  }
     154  
     155  /*[clinic input]
     156  _testcapi.err_setfromerrnowithfilename
     157      error: int
     158      exc: object
     159      value: str(zeroes=True, accept={robuffer, str, NoneType})
     160      /
     161  [clinic start generated code]*/
     162  
     163  static PyObject *
     164  _testcapi_err_setfromerrnowithfilename_impl(PyObject *module, int error,
     165                                              PyObject *exc, const char *value,
     166                                              Py_ssize_t value_length)
     167  /*[clinic end generated code: output=d02df5749a01850e input=ff7c384234bf097f]*/
     168  {
     169      NULLABLE(exc);
     170      errno = error;
     171      PyErr_SetFromErrnoWithFilename(exc, value);
     172      return NULL;
     173  }
     174  
     175  /*[clinic input]
     176  _testcapi.raise_exception
     177      exception as exc: object
     178      num_args: int
     179      /
     180  [clinic start generated code]*/
     181  
     182  static PyObject *
     183  _testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args)
     184  /*[clinic end generated code: output=eb0a9c5d69e0542d input=83d6262c3829d088]*/
     185  {
     186      PyObject *exc_args = PyTuple_New(num_args);
     187      if (exc_args == NULL) {
     188          return NULL;
     189      }
     190      for (int i = 0; i < num_args; ++i) {
     191          PyObject *v = PyLong_FromLong(i);
     192          if (v == NULL) {
     193              Py_DECREF(exc_args);
     194              return NULL;
     195          }
     196          PyTuple_SET_ITEM(exc_args, i, v);
     197      }
     198      PyErr_SetObject(exc, exc_args);
     199      Py_DECREF(exc_args);
     200      return NULL;
     201  }
     202  
     203  /*[clinic input]
     204  _testcapi.raise_memoryerror
     205  [clinic start generated code]*/
     206  
     207  static PyObject *
     208  _testcapi_raise_memoryerror_impl(PyObject *module)
     209  /*[clinic end generated code: output=dd057803fb0131e6 input=6ca521bd07fb73cb]*/
     210  {
     211      return PyErr_NoMemory();
     212  }
     213  
     214  /*[clinic input]
     215  _testcapi.fatal_error
     216      message: str(accept={robuffer})
     217      release_gil: bool = False
     218      /
     219  [clinic start generated code]*/
     220  
     221  static PyObject *
     222  _testcapi_fatal_error_impl(PyObject *module, const char *message,
     223                             int release_gil)
     224  /*[clinic end generated code: output=9c3237116e6a03e8 input=1be357a2ccb04c8c]*/
     225  {
     226      if (release_gil) {
     227          Py_BEGIN_ALLOW_THREADS
     228          Py_FatalError(message);
     229          Py_END_ALLOW_THREADS
     230      }
     231      else {
     232          Py_FatalError(message);
     233      }
     234      // Py_FatalError() does not return, but exits the process.
     235      Py_RETURN_NONE;
     236  }
     237  
     238  /*[clinic input]
     239  _testcapi.set_exc_info
     240      new_type: object
     241      new_value: object
     242      new_tb: object
     243      /
     244  [clinic start generated code]*/
     245  
     246  static PyObject *
     247  _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type,
     248                              PyObject *new_value, PyObject *new_tb)
     249  /*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/
     250  {
     251      PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR;
     252      PyErr_GetExcInfo(&type, &value, &tb);
     253  
     254      Py_INCREF(new_type);
     255      Py_INCREF(new_value);
     256      Py_INCREF(new_tb);
     257      PyErr_SetExcInfo(new_type, new_value, new_tb);
     258  
     259      PyObject *orig_exc = PyTuple_Pack(3,
     260              type  ? type  : Py_None,
     261              value ? value : Py_None,
     262              tb    ? tb    : Py_None);
     263      Py_XDECREF(type);
     264      Py_XDECREF(value);
     265      Py_XDECREF(tb);
     266      return orig_exc;
     267  }
     268  
     269  /*[clinic input]
     270  _testcapi.set_exception
     271      new_exc: object
     272      /
     273  [clinic start generated code]*/
     274  
     275  static PyObject *
     276  _testcapi_set_exception(PyObject *module, PyObject *new_exc)
     277  /*[clinic end generated code: output=8b969b35d029e96d input=c89d4ca966c69738]*/
     278  {
     279      PyObject *exc = PyErr_GetHandledException();
     280      assert(PyExceptionInstance_Check(exc) || exc == NULL);
     281      PyErr_SetHandledException(new_exc);
     282      return exc;
     283  }
     284  
     285  /*[clinic input]
     286  _testcapi.write_unraisable_exc
     287      exception as exc: object
     288      err_msg: object
     289      obj: object
     290      /
     291  [clinic start generated code]*/
     292  
     293  static PyObject *
     294  _testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc,
     295                                      PyObject *err_msg, PyObject *obj)
     296  /*[clinic end generated code: output=39827c5e0a8c2092 input=582498da5b2ee6cf]*/
     297  {
     298  
     299      const char *err_msg_utf8;
     300      if (err_msg != Py_None) {
     301          err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
     302          if (err_msg_utf8 == NULL) {
     303              return NULL;
     304          }
     305      }
     306      else {
     307          err_msg_utf8 = NULL;
     308      }
     309  
     310      PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
     311      _PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
     312      Py_RETURN_NONE;
     313  }
     314  
     315  /*[clinic input]
     316  _testcapi.traceback_print
     317      traceback: object
     318      file: object
     319      /
     320  To test the format of tracebacks as printed out.
     321  [clinic start generated code]*/
     322  
     323  static PyObject *
     324  _testcapi_traceback_print_impl(PyObject *module, PyObject *traceback,
     325                                 PyObject *file)
     326  /*[clinic end generated code: output=17074ecf9d95cf30 input=9423f2857b008ca8]*/
     327  {
     328      if (PyTraceBack_Print(traceback, file) < 0) {
     329          return NULL;
     330      }
     331      Py_RETURN_NONE;
     332  }
     333  
     334  /*[clinic input]
     335  _testcapi.unstable_exc_prep_reraise_star
     336      orig: object
     337      excs: object
     338      /
     339  To test PyUnstable_Exc_PrepReraiseStar.
     340  [clinic start generated code]*/
     341  
     342  static PyObject *
     343  _testcapi_unstable_exc_prep_reraise_star_impl(PyObject *module,
     344                                                PyObject *orig, PyObject *excs)
     345  /*[clinic end generated code: output=850cf008e0563c77 input=27fbcda2203eb301]*/
     346  {
     347      return PyUnstable_Exc_PrepReraiseStar(orig, excs);
     348  }
     349  
     350  
     351  /*
     352   * Define the PyRecurdingInfinitelyError_Type
     353   */
     354  
     355  static PyTypeObject PyRecursingInfinitelyError_Type;
     356  
     357  static int
     358  recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
     359  {
     360      PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
     361  
     362      /* Instantiating this exception starts infinite recursion. */
     363      Py_INCREF(type);
     364      PyErr_SetObject(type, NULL);
     365      return -1;
     366  }
     367  
     368  static PyTypeObject PyRecursingInfinitelyError_Type = {
     369      .tp_name = "RecursingInfinitelyError",
     370      .tp_basicsize = sizeof(PyBaseExceptionObject),
     371      .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     372      .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."),
     373      .tp_init = (initproc)recurse_infinitely_error_init,
     374  };
     375  
     376  static PyMethodDef test_methods[] = {
     377      {"err_restore",             err_restore,                     METH_VARARGS},
     378      _TESTCAPI_ERR_SET_RAISED_METHODDEF
     379      _TESTCAPI_EXCEPTION_PRINT_METHODDEF
     380      _TESTCAPI_FATAL_ERROR_METHODDEF
     381      _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF
     382      _TESTCAPI_EXC_SET_OBJECT_METHODDEF
     383      _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF
     384      _TESTCAPI_ERR_SETSTRING_METHODDEF
     385      _TESTCAPI_ERR_SETFROMERRNOWITHFILENAME_METHODDEF
     386      _TESTCAPI_RAISE_EXCEPTION_METHODDEF
     387      _TESTCAPI_RAISE_MEMORYERROR_METHODDEF
     388      _TESTCAPI_SET_EXC_INFO_METHODDEF
     389      _TESTCAPI_SET_EXCEPTION_METHODDEF
     390      _TESTCAPI_TRACEBACK_PRINT_METHODDEF
     391      _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF
     392      _TESTCAPI_UNSTABLE_EXC_PREP_RERAISE_STAR_METHODDEF
     393      {NULL},
     394  };
     395  
     396  int
     397  _PyTestCapi_Init_Exceptions(PyObject *mod)
     398  {
     399      PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
     400      if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
     401          return -1;
     402      }
     403      if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError",
     404                                (PyObject *)&PyRecursingInfinitelyError_Type) < 0)
     405      {
     406          return -1;
     407      }
     408  
     409      if (PyModule_AddFunctions(mod, test_methods) < 0) {
     410          return -1;
     411      }
     412  
     413      return 0;
     414  }