| // clinic/exceptions.c.h uses internal pycore_modsupport.h API |
| #define PYTESTCAPI_NEED_INTERNAL_API |
| |
| #include "parts.h" |
| #include "util.h" |
| #include "clinic/exceptions.c.h" |
| |
| |
| /*[clinic input] |
| module _testcapi |
| [clinic start generated code]*/ |
| /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ |
| |
| /*[clinic input] |
| _testcapi.err_set_raised |
| exception as exc: object |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_err_set_raised(PyObject *module, PyObject *exc) |
| /*[clinic end generated code: output=0a0c7743961fcae5 input=c5f7331864a94df9]*/ |
| { |
| Py_INCREF(exc); |
| PyErr_SetRaisedException(exc); |
| assert(PyErr_Occurred()); |
| return NULL; |
| } |
| |
| static PyObject * |
| err_restore(PyObject *self, PyObject *args) { |
| PyObject *type = NULL, *value = NULL, *traceback = NULL; |
| switch(PyTuple_Size(args)) { |
| case 3: |
| traceback = PyTuple_GetItem(args, 2); |
| Py_INCREF(traceback); |
| /* fall through */ |
| case 2: |
| value = PyTuple_GetItem(args, 1); |
| Py_INCREF(value); |
| /* fall through */ |
| case 1: |
| type = PyTuple_GetItem(args, 0); |
| Py_INCREF(type); |
| break; |
| default: |
| PyErr_SetString(PyExc_TypeError, |
| "wrong number of arguments"); |
| return NULL; |
| } |
| PyErr_Restore(type, value, traceback); |
| assert(PyErr_Occurred()); |
| return NULL; |
| } |
| |
| /*[clinic input] |
| _testcapi.exception_print |
| exception as exc: object |
| legacy: bool = False |
| / |
| |
| To test the format of exceptions as printed out. |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy) |
| /*[clinic end generated code: output=3f04fe0c18412ae0 input=c76f42cb94136dbf]*/ |
| { |
| if (legacy) { |
| PyObject *tb = NULL; |
| if (PyExceptionInstance_Check(exc)) { |
| tb = PyException_GetTraceback(exc); |
| } |
| PyErr_Display((PyObject *) Py_TYPE(exc), exc, tb); |
| Py_XDECREF(tb); |
| } |
| else { |
| PyErr_DisplayException(exc); |
| } |
| Py_RETURN_NONE; |
| } |
| |
| /*[clinic input] |
| _testcapi.make_exception_with_doc |
| name: str |
| doc: str = NULL |
| base: object = NULL |
| dict: object = NULL |
| |
| Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_make_exception_with_doc_impl(PyObject *module, const char *name, |
| const char *doc, PyObject *base, |
| PyObject *dict) |
| /*[clinic end generated code: output=439f0d963c1ce2c4 input=23a73013f8a8795a]*/ |
| { |
| return PyErr_NewExceptionWithDoc(name, doc, base, dict); |
| } |
| |
| /*[clinic input] |
| _testcapi.exc_set_object |
| exception as exc: object |
| obj: object |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj) |
| /*[clinic end generated code: output=34c8c7c83e5c8463 input=fc530aafb1b0a360]*/ |
| { |
| PyErr_SetObject(exc, obj); |
| return NULL; |
| } |
| |
| /*[clinic input] |
| _testcapi.exc_set_object_fetch = _testcapi.exc_set_object |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, |
| PyObject *obj) |
| /*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/ |
| { |
| PyObject *type = UNINITIALIZED_PTR; |
| PyObject *value = UNINITIALIZED_PTR; |
| PyObject *tb = UNINITIALIZED_PTR; |
| |
| PyErr_SetObject(exc, obj); |
| PyErr_Fetch(&type, &value, &tb); |
| assert(type != UNINITIALIZED_PTR); |
| assert(value != UNINITIALIZED_PTR); |
| assert(tb != UNINITIALIZED_PTR); |
| Py_XDECREF(type); |
| Py_XDECREF(tb); |
| return value; |
| } |
| |
| /*[clinic input] |
| _testcapi.err_setstring |
| exc: object |
| value: str(zeroes=True, accept={robuffer, str, NoneType}) |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_err_setstring_impl(PyObject *module, PyObject *exc, |
| const char *value, Py_ssize_t value_length) |
| /*[clinic end generated code: output=fba8705e5703dd3f input=e8a95fad66d9004b]*/ |
| { |
| NULLABLE(exc); |
| PyErr_SetString(exc, value); |
| return NULL; |
| } |
| |
| /*[clinic input] |
| _testcapi.err_setfromerrnowithfilename |
| error: int |
| exc: object |
| value: str(zeroes=True, accept={robuffer, str, NoneType}) |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_err_setfromerrnowithfilename_impl(PyObject *module, int error, |
| PyObject *exc, const char *value, |
| Py_ssize_t value_length) |
| /*[clinic end generated code: output=d02df5749a01850e input=ff7c384234bf097f]*/ |
| { |
| NULLABLE(exc); |
| errno = error; |
| PyErr_SetFromErrnoWithFilename(exc, value); |
| return NULL; |
| } |
| |
| /*[clinic input] |
| _testcapi.raise_exception |
| exception as exc: object |
| num_args: int |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args) |
| /*[clinic end generated code: output=eb0a9c5d69e0542d input=83d6262c3829d088]*/ |
| { |
| PyObject *exc_args = PyTuple_New(num_args); |
| if (exc_args == NULL) { |
| return NULL; |
| } |
| for (int i = 0; i < num_args; ++i) { |
| PyObject *v = PyLong_FromLong(i); |
| if (v == NULL) { |
| Py_DECREF(exc_args); |
| return NULL; |
| } |
| PyTuple_SET_ITEM(exc_args, i, v); |
| } |
| PyErr_SetObject(exc, exc_args); |
| Py_DECREF(exc_args); |
| return NULL; |
| } |
| |
| /*[clinic input] |
| _testcapi.raise_memoryerror |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_raise_memoryerror_impl(PyObject *module) |
| /*[clinic end generated code: output=dd057803fb0131e6 input=6ca521bd07fb73cb]*/ |
| { |
| return PyErr_NoMemory(); |
| } |
| |
| /*[clinic input] |
| _testcapi.fatal_error |
| message: str(accept={robuffer}) |
| release_gil: bool = False |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_fatal_error_impl(PyObject *module, const char *message, |
| int release_gil) |
| /*[clinic end generated code: output=9c3237116e6a03e8 input=1be357a2ccb04c8c]*/ |
| { |
| if (release_gil) { |
| Py_BEGIN_ALLOW_THREADS |
| Py_FatalError(message); |
| Py_END_ALLOW_THREADS |
| } |
| else { |
| Py_FatalError(message); |
| } |
| // Py_FatalError() does not return, but exits the process. |
| Py_RETURN_NONE; |
| } |
| |
| /*[clinic input] |
| _testcapi.set_exc_info |
| new_type: object |
| new_value: object |
| new_tb: object |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, |
| PyObject *new_value, PyObject *new_tb) |
| /*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/ |
| { |
| PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR; |
| PyErr_GetExcInfo(&type, &value, &tb); |
| |
| Py_INCREF(new_type); |
| Py_INCREF(new_value); |
| Py_INCREF(new_tb); |
| PyErr_SetExcInfo(new_type, new_value, new_tb); |
| |
| PyObject *orig_exc = PyTuple_Pack(3, |
| type ? type : Py_None, |
| value ? value : Py_None, |
| tb ? tb : Py_None); |
| Py_XDECREF(type); |
| Py_XDECREF(value); |
| Py_XDECREF(tb); |
| return orig_exc; |
| } |
| |
| /*[clinic input] |
| _testcapi.set_exception |
| new_exc: object |
| / |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_set_exception(PyObject *module, PyObject *new_exc) |
| /*[clinic end generated code: output=8b969b35d029e96d input=c89d4ca966c69738]*/ |
| { |
| PyObject *exc = PyErr_GetHandledException(); |
| assert(PyExceptionInstance_Check(exc) || exc == NULL); |
| PyErr_SetHandledException(new_exc); |
| return exc; |
| } |
| |
| /*[clinic input] |
| _testcapi.traceback_print |
| traceback: object |
| file: object |
| / |
| To test the format of tracebacks as printed out. |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_traceback_print_impl(PyObject *module, PyObject *traceback, |
| PyObject *file) |
| /*[clinic end generated code: output=17074ecf9d95cf30 input=9423f2857b008ca8]*/ |
| { |
| if (PyTraceBack_Print(traceback, file) < 0) { |
| return NULL; |
| } |
| Py_RETURN_NONE; |
| } |
| |
| static PyObject * |
| err_writeunraisable(PyObject *Py_UNUSED(module), PyObject *args) |
| { |
| PyObject *exc, *obj; |
| if (!PyArg_ParseTuple(args, "OO", &exc, &obj)) { |
| return NULL; |
| } |
| NULLABLE(exc); |
| NULLABLE(obj); |
| if (exc) { |
| PyErr_SetRaisedException(Py_NewRef(exc)); |
| } |
| PyErr_WriteUnraisable(obj); |
| Py_RETURN_NONE; |
| } |
| |
| static PyObject * |
| err_formatunraisable(PyObject *Py_UNUSED(module), PyObject *args) |
| { |
| PyObject *exc; |
| const char *fmt; |
| Py_ssize_t fmtlen; |
| PyObject *objs[10] = {NULL}; |
| |
| if (!PyArg_ParseTuple(args, "Oz#|OOOOOOOOOO", &exc, &fmt, &fmtlen, |
| &objs[0], &objs[1], &objs[2], &objs[3], &objs[4], |
| &objs[5], &objs[6], &objs[7], &objs[8], &objs[9])) |
| { |
| return NULL; |
| } |
| NULLABLE(exc); |
| if (exc) { |
| PyErr_SetRaisedException(Py_NewRef(exc)); |
| } |
| PyErr_FormatUnraisable(fmt, |
| objs[0], objs[1], objs[2], objs[3], objs[4], |
| objs[5], objs[6], objs[7], objs[8], objs[9]); |
| Py_RETURN_NONE; |
| } |
| |
| /*[clinic input] |
| _testcapi.unstable_exc_prep_reraise_star |
| orig: object |
| excs: object |
| / |
| To test PyUnstable_Exc_PrepReraiseStar. |
| [clinic start generated code]*/ |
| |
| static PyObject * |
| _testcapi_unstable_exc_prep_reraise_star_impl(PyObject *module, |
| PyObject *orig, PyObject *excs) |
| /*[clinic end generated code: output=850cf008e0563c77 input=27fbcda2203eb301]*/ |
| { |
| return PyUnstable_Exc_PrepReraiseStar(orig, excs); |
| } |
| |
| |
| /* |
| * Define the PyRecurdingInfinitelyError_Type |
| */ |
| |
| static PyTypeObject PyRecursingInfinitelyError_Type; |
| |
| static int |
| recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds) |
| { |
| PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type; |
| |
| /* Instantiating this exception starts infinite recursion. */ |
| Py_INCREF(type); |
| PyErr_SetObject(type, NULL); |
| return -1; |
| } |
| |
| static PyTypeObject PyRecursingInfinitelyError_Type = { |
| .tp_name = "RecursingInfinitelyError", |
| .tp_basicsize = sizeof(PyBaseExceptionObject), |
| .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, |
| .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."), |
| .tp_init = (initproc)recurse_infinitely_error_init, |
| }; |
| |
| static PyMethodDef test_methods[] = { |
| {"err_restore", err_restore, METH_VARARGS}, |
| {"err_writeunraisable", err_writeunraisable, METH_VARARGS}, |
| {"err_formatunraisable", err_formatunraisable, METH_VARARGS}, |
| _TESTCAPI_ERR_SET_RAISED_METHODDEF |
| _TESTCAPI_EXCEPTION_PRINT_METHODDEF |
| _TESTCAPI_FATAL_ERROR_METHODDEF |
| _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF |
| _TESTCAPI_EXC_SET_OBJECT_METHODDEF |
| _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF |
| _TESTCAPI_ERR_SETSTRING_METHODDEF |
| _TESTCAPI_ERR_SETFROMERRNOWITHFILENAME_METHODDEF |
| _TESTCAPI_RAISE_EXCEPTION_METHODDEF |
| _TESTCAPI_RAISE_MEMORYERROR_METHODDEF |
| _TESTCAPI_SET_EXC_INFO_METHODDEF |
| _TESTCAPI_SET_EXCEPTION_METHODDEF |
| _TESTCAPI_TRACEBACK_PRINT_METHODDEF |
| _TESTCAPI_UNSTABLE_EXC_PREP_RERAISE_STAR_METHODDEF |
| {NULL}, |
| }; |
| |
| int |
| _PyTestCapi_Init_Exceptions(PyObject *mod) |
| { |
| PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception; |
| if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) { |
| return -1; |
| } |
| if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError", |
| (PyObject *)&PyRecursingInfinitelyError_Type) < 0) |
| { |
| return -1; |
| } |
| |
| if (PyModule_AddFunctions(mod, test_methods) < 0) { |
| return -1; |
| } |
| |
| return 0; |
| } |