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