Branch data Line data Source code
1 : : #include "parts.h"
2 : :
3 : : static PyObject *
4 : 0 : err_set_raised(PyObject *self, PyObject *exc)
5 : : {
6 : 0 : Py_INCREF(exc);
7 : 0 : PyErr_SetRaisedException(exc);
8 [ # # ]: 0 : assert(PyErr_Occurred());
9 : 0 : return NULL;
10 : : }
11 : :
12 : : static PyObject *
13 : 0 : err_restore(PyObject *self, PyObject *args) {
14 : 0 : PyObject *type = NULL, *value = NULL, *traceback = NULL;
15 [ # # # # ]: 0 : switch(PyTuple_Size(args)) {
16 : 0 : case 3:
17 : 0 : traceback = PyTuple_GetItem(args, 2);
18 : 0 : Py_INCREF(traceback);
19 : : /* fall through */
20 : 0 : case 2:
21 : 0 : value = PyTuple_GetItem(args, 1);
22 : 0 : Py_INCREF(value);
23 : : /* fall through */
24 : 0 : case 1:
25 : 0 : type = PyTuple_GetItem(args, 0);
26 : 0 : Py_INCREF(type);
27 : 0 : break;
28 : 0 : default:
29 : 0 : PyErr_SetString(PyExc_TypeError,
30 : : "wrong number of arguments");
31 : 0 : return NULL;
32 : : }
33 : 0 : PyErr_Restore(type, value, traceback);
34 [ # # ]: 0 : assert(PyErr_Occurred());
35 : 0 : return NULL;
36 : : }
37 : :
38 : : /* To test the format of exceptions as printed out. */
39 : : static PyObject *
40 : 0 : exception_print(PyObject *self, PyObject *args)
41 : : {
42 : : PyObject *exc;
43 : :
44 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "O:exception_print", &exc)) {
45 : 0 : return NULL;
46 : : }
47 : :
48 : 0 : PyErr_DisplayException(exc);
49 : 0 : Py_RETURN_NONE;
50 : : }
51 : :
52 : : /* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException).
53 : : Run via Lib/test/test_exceptions.py */
54 : : static PyObject *
55 : 0 : make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
56 : : {
57 : : const char *name;
58 : 0 : const char *doc = NULL;
59 : 0 : PyObject *base = NULL;
60 : 0 : PyObject *dict = NULL;
61 : :
62 : : static char *kwlist[] = {"name", "doc", "base", "dict", NULL};
63 : :
64 [ # # ]: 0 : if (!PyArg_ParseTupleAndKeywords(args, kwargs,
65 : : "s|sOO:make_exception_with_doc", kwlist,
66 : : &name, &doc, &base, &dict))
67 : : {
68 : 0 : return NULL;
69 : : }
70 : :
71 : 0 : return PyErr_NewExceptionWithDoc(name, doc, base, dict);
72 : : }
73 : :
74 : : static PyObject *
75 : 0 : exc_set_object(PyObject *self, PyObject *args)
76 : : {
77 : : PyObject *exc;
78 : : PyObject *obj;
79 : :
80 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) {
81 : 0 : return NULL;
82 : : }
83 : :
84 : 0 : PyErr_SetObject(exc, obj);
85 : 0 : return NULL;
86 : : }
87 : :
88 : : static PyObject *
89 : 0 : exc_set_object_fetch(PyObject *self, PyObject *args)
90 : : {
91 : : PyObject *exc;
92 : : PyObject *obj;
93 : : PyObject *type;
94 : : PyObject *value;
95 : : PyObject *tb;
96 : :
97 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) {
98 : 0 : return NULL;
99 : : }
100 : :
101 : 0 : PyErr_SetObject(exc, obj);
102 : 0 : PyErr_Fetch(&type, &value, &tb);
103 : 0 : Py_XDECREF(type);
104 : 0 : Py_XDECREF(tb);
105 : 0 : return value;
106 : : }
107 : :
108 : : static PyObject *
109 : 0 : raise_exception(PyObject *self, PyObject *args)
110 : : {
111 : : PyObject *exc;
112 : : int num_args;
113 : :
114 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "Oi:raise_exception", &exc, &num_args)) {
115 : 0 : return NULL;
116 : : }
117 : :
118 : 0 : PyObject *exc_args = PyTuple_New(num_args);
119 [ # # ]: 0 : if (exc_args == NULL) {
120 : 0 : return NULL;
121 : : }
122 [ # # ]: 0 : for (int i = 0; i < num_args; ++i) {
123 : 0 : PyObject *v = PyLong_FromLong(i);
124 [ # # ]: 0 : if (v == NULL) {
125 : 0 : Py_DECREF(exc_args);
126 : 0 : return NULL;
127 : : }
128 : 0 : PyTuple_SET_ITEM(exc_args, i, v);
129 : : }
130 : 0 : PyErr_SetObject(exc, exc_args);
131 : 0 : Py_DECREF(exc_args);
132 : 0 : return NULL;
133 : : }
134 : :
135 : : /* reliably raise a MemoryError */
136 : : static PyObject *
137 : 0 : raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored))
138 : : {
139 : 0 : return PyErr_NoMemory();
140 : : }
141 : :
142 : : static PyObject *
143 : 0 : test_fatal_error(PyObject *self, PyObject *args)
144 : : {
145 : : char *message;
146 : 0 : int release_gil = 0;
147 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) {
148 : 0 : return NULL;
149 : : }
150 [ # # ]: 0 : if (release_gil) {
151 : 0 : Py_BEGIN_ALLOW_THREADS
152 : 0 : Py_FatalError(message);
153 : : Py_END_ALLOW_THREADS
154 : : }
155 : : else {
156 : 0 : Py_FatalError(message);
157 : : }
158 : : // Py_FatalError() does not return, but exits the process.
159 : : Py_RETURN_NONE;
160 : : }
161 : :
162 : : static PyObject *
163 : 0 : test_set_exc_info(PyObject *self, PyObject *args)
164 : : {
165 : : PyObject *new_type, *new_value, *new_tb;
166 : : PyObject *type, *value, *tb;
167 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info",
168 : : &new_type, &new_value, &new_tb))
169 : : {
170 : 0 : return NULL;
171 : : }
172 : :
173 : 0 : PyErr_GetExcInfo(&type, &value, &tb);
174 : :
175 : 0 : Py_INCREF(new_type);
176 : 0 : Py_INCREF(new_value);
177 : 0 : Py_INCREF(new_tb);
178 : 0 : PyErr_SetExcInfo(new_type, new_value, new_tb);
179 : :
180 : 0 : PyObject *orig_exc = PyTuple_Pack(3,
181 [ # # ]: 0 : type ? type : Py_None,
182 [ # # ]: 0 : value ? value : Py_None,
183 [ # # ]: 0 : tb ? tb : Py_None);
184 : 0 : Py_XDECREF(type);
185 : 0 : Py_XDECREF(value);
186 : 0 : Py_XDECREF(tb);
187 : 0 : return orig_exc;
188 : : }
189 : :
190 : : static PyObject *
191 : 0 : test_set_exception(PyObject *self, PyObject *new_exc)
192 : : {
193 : 0 : PyObject *exc = PyErr_GetHandledException();
194 [ # # # # ]: 0 : assert(PyExceptionInstance_Check(exc) || exc == NULL);
195 : :
196 : 0 : PyErr_SetHandledException(new_exc);
197 : 0 : return exc;
198 : : }
199 : :
200 : : static PyObject *
201 : 0 : test_write_unraisable_exc(PyObject *self, PyObject *args)
202 : : {
203 : : PyObject *exc, *err_msg, *obj;
204 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) {
205 : 0 : return NULL;
206 : : }
207 : :
208 : : const char *err_msg_utf8;
209 [ # # ]: 0 : if (err_msg != Py_None) {
210 : 0 : err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
211 [ # # ]: 0 : if (err_msg_utf8 == NULL) {
212 : 0 : return NULL;
213 : : }
214 : : }
215 : : else {
216 : 0 : err_msg_utf8 = NULL;
217 : : }
218 : :
219 : 0 : PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
220 : 0 : _PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
221 : 0 : Py_RETURN_NONE;
222 : : }
223 : :
224 : : /* To test the format of tracebacks as printed out. */
225 : : static PyObject *
226 : 0 : traceback_print(PyObject *self, PyObject *args)
227 : : {
228 : : PyObject *file;
229 : : PyObject *traceback;
230 : :
231 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "OO:traceback_print",
232 : : &traceback, &file))
233 : : {
234 : 0 : return NULL;
235 : : }
236 : :
237 [ # # ]: 0 : if (PyTraceBack_Print(traceback, file) < 0) {
238 : 0 : return NULL;
239 : : }
240 : 0 : Py_RETURN_NONE;
241 : : }
242 : :
243 : :
244 : : /*
245 : : * Define the PyRecurdingInfinitelyError_Type
246 : : */
247 : :
248 : : static PyTypeObject PyRecursingInfinitelyError_Type;
249 : :
250 : : static int
251 : 0 : recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
252 : : {
253 : 0 : PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
254 : :
255 : : /* Instantiating this exception starts infinite recursion. */
256 : 0 : Py_INCREF(type);
257 : 0 : PyErr_SetObject(type, NULL);
258 : 0 : return -1;
259 : : }
260 : :
261 : : static PyTypeObject PyRecursingInfinitelyError_Type = {
262 : : .tp_name = "RecursingInfinitelyError",
263 : : .tp_basicsize = sizeof(PyBaseExceptionObject),
264 : : .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
265 : : .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."),
266 : : .tp_init = (initproc)recurse_infinitely_error_init,
267 : : };
268 : :
269 : : static PyMethodDef test_methods[] = {
270 : : {"err_restore", err_restore, METH_VARARGS},
271 : : {"err_set_raised", err_set_raised, METH_O},
272 : : {"exception_print", exception_print, METH_VARARGS},
273 : : {"fatal_error", test_fatal_error, METH_VARARGS,
274 : : PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
275 : : {"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
276 : : METH_VARARGS | METH_KEYWORDS},
277 : : {"exc_set_object", exc_set_object, METH_VARARGS},
278 : : {"exc_set_object_fetch", exc_set_object_fetch, METH_VARARGS},
279 : : {"raise_exception", raise_exception, METH_VARARGS},
280 : : {"raise_memoryerror", raise_memoryerror, METH_NOARGS},
281 : : {"set_exc_info", test_set_exc_info, METH_VARARGS},
282 : : {"set_exception", test_set_exception, METH_O},
283 : : {"traceback_print", traceback_print, METH_VARARGS},
284 : : {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
285 : : {NULL},
286 : : };
287 : :
288 : : int
289 : 2 : _PyTestCapi_Init_Exceptions(PyObject *mod)
290 : : {
291 : 2 : PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
292 [ - + ]: 2 : if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
293 : 0 : return -1;
294 : : }
295 [ - + ]: 2 : if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError",
296 : : (PyObject *)&PyRecursingInfinitelyError_Type) < 0)
297 : : {
298 : 0 : return -1;
299 : : }
300 : :
301 [ - + ]: 2 : if (PyModule_AddFunctions(mod, test_methods) < 0) {
302 : 0 : return -1;
303 : : }
304 : :
305 : 2 : return 0;
306 : : }
|