/src/cpython/Python/errors.c
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | /* Error handling */ |
3 | | |
4 | | #include "Python.h" |
5 | | #include "pycore_audit.h" // _PySys_Audit() |
6 | | #include "pycore_call.h" // _PyObject_CallNoArgs() |
7 | | #include "pycore_fileutils.h" // _PyFile_Flush |
8 | | #include "pycore_initconfig.h" // _PyStatus_ERR() |
9 | | #include "pycore_pyerrors.h" // _PyErr_Format() |
10 | | #include "pycore_pystate.h" // _PyThreadState_GET() |
11 | | #include "pycore_runtime.h" // _Py_ID() |
12 | | #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() |
13 | | #include "pycore_traceback.h" // _PyTraceBack_FromFrame() |
14 | | #include "pycore_unicodeobject.h" // _PyUnicode_Equal() |
15 | | |
16 | | #ifdef MS_WINDOWS |
17 | | # include <windows.h> |
18 | | # include <winbase.h> |
19 | | # include <stdlib.h> // _sys_nerr |
20 | | #endif |
21 | | |
22 | | |
23 | | void |
24 | | _PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc) |
25 | 153M | { |
26 | 153M | PyObject *old_exc = tstate->current_exception; |
27 | 153M | tstate->current_exception = exc; |
28 | 153M | Py_XDECREF(old_exc); |
29 | 153M | } |
30 | | |
31 | | static PyObject* |
32 | | _PyErr_CreateException(PyObject *exception_type, PyObject *value) |
33 | 15.2M | { |
34 | 15.2M | PyObject *exc; |
35 | | |
36 | 15.2M | if (value == NULL || value == Py_None) { |
37 | 113k | exc = _PyObject_CallNoArgs(exception_type); |
38 | 113k | } |
39 | 15.0M | else if (PyTuple_Check(value)) { |
40 | 16.2k | exc = PyObject_Call(exception_type, value, NULL); |
41 | 16.2k | } |
42 | 15.0M | else { |
43 | 15.0M | exc = PyObject_CallOneArg(exception_type, value); |
44 | 15.0M | } |
45 | | |
46 | 15.2M | if (exc != NULL && !PyExceptionInstance_Check(exc)) { |
47 | 0 | PyErr_Format(PyExc_TypeError, |
48 | 0 | "calling %R should have returned an instance of " |
49 | 0 | "BaseException, not %s", |
50 | 0 | exception_type, Py_TYPE(exc)->tp_name); |
51 | 0 | Py_CLEAR(exc); |
52 | 0 | } |
53 | | |
54 | 15.2M | return exc; |
55 | 15.2M | } |
56 | | |
57 | | void |
58 | | _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, |
59 | | PyObject *traceback) |
60 | 74.6M | { |
61 | 74.6M | if (type == NULL) { |
62 | 42.4M | assert(value == NULL); |
63 | 42.4M | assert(traceback == NULL); |
64 | 42.4M | _PyErr_SetRaisedException(tstate, NULL); |
65 | 42.4M | return; |
66 | 42.4M | } |
67 | 32.1M | assert(PyExceptionClass_Check(type)); |
68 | 32.1M | if (value != NULL && type == (PyObject *)Py_TYPE(value)) { |
69 | | /* Already normalized */ |
70 | | #ifdef Py_DEBUG |
71 | | PyObject *tb = PyException_GetTraceback(value); |
72 | | assert(tb != Py_None); |
73 | | Py_XDECREF(tb); |
74 | | #endif |
75 | 32.1M | } |
76 | 0 | else { |
77 | 0 | PyObject *exc = _PyErr_CreateException(type, value); |
78 | 0 | Py_XDECREF(value); |
79 | 0 | if (exc == NULL) { |
80 | 0 | Py_DECREF(type); |
81 | 0 | Py_XDECREF(traceback); |
82 | 0 | return; |
83 | 0 | } |
84 | 0 | value = exc; |
85 | 0 | } |
86 | 32.1M | assert(PyExceptionInstance_Check(value)); |
87 | 32.1M | if (traceback != NULL) { |
88 | 2.92k | if (PyException_SetTraceback(value, traceback) < 0) { |
89 | 0 | Py_DECREF(traceback); |
90 | 0 | Py_DECREF(value); |
91 | 0 | Py_DECREF(type); |
92 | 0 | return; |
93 | 0 | } |
94 | 2.92k | Py_DECREF(traceback); |
95 | 2.92k | } |
96 | 32.1M | _PyErr_SetRaisedException(tstate, value); |
97 | 32.1M | Py_DECREF(type); |
98 | 32.1M | } |
99 | | |
100 | | void |
101 | | PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) |
102 | 10.7k | { |
103 | 10.7k | PyThreadState *tstate = _PyThreadState_GET(); |
104 | 10.7k | _PyErr_Restore(tstate, type, value, traceback); |
105 | 10.7k | } |
106 | | |
107 | | void |
108 | | PyErr_SetRaisedException(PyObject *exc) |
109 | 78.4M | { |
110 | 78.4M | PyThreadState *tstate = _PyThreadState_GET(); |
111 | 78.4M | _PyErr_SetRaisedException(tstate, exc); |
112 | 78.4M | } |
113 | | |
114 | | _PyErr_StackItem * |
115 | | _PyErr_GetTopmostException(PyThreadState *tstate) |
116 | 32.1M | { |
117 | 32.1M | _PyErr_StackItem *exc_info = tstate->exc_info; |
118 | 32.1M | assert(exc_info); |
119 | | |
120 | 84.9M | while (exc_info->exc_value == NULL && exc_info->previous_item != NULL) |
121 | 52.7M | { |
122 | 52.7M | exc_info = exc_info->previous_item; |
123 | 52.7M | } |
124 | 32.1M | assert(!Py_IsNone(exc_info->exc_value)); |
125 | 32.1M | return exc_info; |
126 | 32.1M | } |
127 | | |
128 | | static PyObject * |
129 | | get_normalization_failure_note(PyThreadState *tstate, PyObject *exception, PyObject *value) |
130 | 0 | { |
131 | 0 | PyObject *args = PyObject_Repr(value); |
132 | 0 | if (args == NULL) { |
133 | 0 | _PyErr_Clear(tstate); |
134 | 0 | args = PyUnicode_FromFormat("<unknown>"); |
135 | 0 | } |
136 | 0 | PyObject *note; |
137 | 0 | const char *tpname = ((PyTypeObject*)exception)->tp_name; |
138 | 0 | if (args == NULL) { |
139 | 0 | _PyErr_Clear(tstate); |
140 | 0 | note = PyUnicode_FromFormat("Normalization failed: type=%s", tpname); |
141 | 0 | } |
142 | 0 | else { |
143 | 0 | note = PyUnicode_FromFormat("Normalization failed: type=%s args=%S", |
144 | 0 | tpname, args); |
145 | 0 | Py_DECREF(args); |
146 | 0 | } |
147 | 0 | return note; |
148 | 0 | } |
149 | | |
150 | | void |
151 | | _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) |
152 | 32.1M | { |
153 | 32.1M | PyObject *exc_value; |
154 | 32.1M | PyObject *tb = NULL; |
155 | | |
156 | 32.1M | if (exception != NULL && |
157 | 32.1M | !PyExceptionClass_Check(exception)) { |
158 | 0 | _PyErr_Format(tstate, PyExc_SystemError, |
159 | 0 | "_PyErr_SetObject: " |
160 | 0 | "exception %R is not a BaseException subclass", |
161 | 0 | exception); |
162 | 0 | return; |
163 | 0 | } |
164 | | /* Normalize the exception */ |
165 | 32.1M | int is_subclass = 0; |
166 | 32.1M | if (value != NULL && PyExceptionInstance_Check(value)) { |
167 | 16.9M | is_subclass = PyObject_IsSubclass((PyObject *)Py_TYPE(value), exception); |
168 | 16.9M | if (is_subclass < 0) { |
169 | 0 | return; |
170 | 0 | } |
171 | 16.9M | } |
172 | 32.1M | Py_XINCREF(value); |
173 | 32.1M | if (!is_subclass) { |
174 | | /* We must normalize the value right now */ |
175 | | |
176 | | /* Issue #23571: functions must not be called with an |
177 | | exception set */ |
178 | 15.2M | _PyErr_Clear(tstate); |
179 | | |
180 | 15.2M | PyObject *fixed_value = _PyErr_CreateException(exception, value); |
181 | 15.2M | if (fixed_value == NULL) { |
182 | 0 | PyObject *exc = _PyErr_GetRaisedException(tstate); |
183 | 0 | assert(PyExceptionInstance_Check(exc)); |
184 | |
|
185 | 0 | PyObject *note = get_normalization_failure_note(tstate, exception, value); |
186 | 0 | Py_XDECREF(value); |
187 | 0 | if (note != NULL) { |
188 | | /* ignore errors in _PyException_AddNote - they will be overwritten below */ |
189 | 0 | _PyException_AddNote(exc, note); |
190 | 0 | Py_DECREF(note); |
191 | 0 | } |
192 | 0 | _PyErr_SetRaisedException(tstate, exc); |
193 | 0 | return; |
194 | 0 | } |
195 | 15.2M | Py_XSETREF(value, fixed_value); |
196 | 15.2M | } |
197 | | |
198 | 32.1M | exc_value = _PyErr_GetTopmostException(tstate)->exc_value; |
199 | 32.1M | if (exc_value != NULL && exc_value != Py_None) { |
200 | | /* Implicit exception chaining */ |
201 | 266k | Py_INCREF(exc_value); |
202 | | /* Avoid creating new reference cycles through the |
203 | | context chain, while taking care not to hang on |
204 | | pre-existing ones. |
205 | | This is O(chain length) but context chains are |
206 | | usually very short. Sensitive readers may try |
207 | | to inline the call to PyException_GetContext. */ |
208 | 266k | if (exc_value != value) { |
209 | 266k | PyObject *o = exc_value, *context; |
210 | 266k | PyObject *slow_o = o; /* Floyd's cycle detection algo */ |
211 | 266k | int slow_update_toggle = 0; |
212 | 353k | while ((context = PyException_GetContext(o))) { |
213 | 87.2k | Py_DECREF(context); |
214 | 87.2k | if (context == value) { |
215 | 0 | PyException_SetContext(o, NULL); |
216 | 0 | break; |
217 | 0 | } |
218 | 87.2k | o = context; |
219 | 87.2k | if (o == slow_o) { |
220 | | /* pre-existing cycle - all exceptions on the |
221 | | path were visited and checked. */ |
222 | 0 | break; |
223 | 0 | } |
224 | 87.2k | if (slow_update_toggle) { |
225 | 13.3k | slow_o = PyException_GetContext(slow_o); |
226 | 13.3k | Py_DECREF(slow_o); |
227 | 13.3k | } |
228 | 87.2k | slow_update_toggle = !slow_update_toggle; |
229 | 87.2k | } |
230 | 266k | PyException_SetContext(value, exc_value); |
231 | 266k | } |
232 | 0 | else { |
233 | 0 | Py_DECREF(exc_value); |
234 | 0 | } |
235 | 266k | } |
236 | 32.1M | assert(value != NULL); |
237 | 32.1M | if (PyExceptionInstance_Check(value)) |
238 | 32.1M | tb = PyException_GetTraceback(value); |
239 | 32.1M | _PyErr_Restore(tstate, Py_NewRef(Py_TYPE(value)), value, tb); |
240 | 32.1M | } |
241 | | |
242 | | void |
243 | | PyErr_SetObject(PyObject *exception, PyObject *value) |
244 | 241k | { |
245 | 241k | PyThreadState *tstate = _PyThreadState_GET(); |
246 | 241k | _PyErr_SetObject(tstate, exception, value); |
247 | 241k | } |
248 | | |
249 | | /* Set a key error with the specified argument, wrapping it in a |
250 | | * tuple automatically so that tuple keys are not unpacked as the |
251 | | * exception arguments. */ |
252 | | void |
253 | | _PyErr_SetKeyError(PyObject *arg) |
254 | 4.07M | { |
255 | 4.07M | PyThreadState *tstate = _PyThreadState_GET(); |
256 | 4.07M | PyObject *exc = PyObject_CallOneArg(PyExc_KeyError, arg); |
257 | 4.07M | if (!exc) { |
258 | | /* caller will expect error to be set anyway */ |
259 | 0 | return; |
260 | 0 | } |
261 | | |
262 | 4.07M | _PyErr_SetObject(tstate, (PyObject*)Py_TYPE(exc), exc); |
263 | 4.07M | Py_DECREF(exc); |
264 | 4.07M | } |
265 | | |
266 | | void |
267 | | _PyErr_SetNone(PyThreadState *tstate, PyObject *exception) |
268 | 113k | { |
269 | 113k | _PyErr_SetObject(tstate, exception, (PyObject *)NULL); |
270 | 113k | } |
271 | | |
272 | | |
273 | | void |
274 | | PyErr_SetNone(PyObject *exception) |
275 | 113k | { |
276 | 113k | PyThreadState *tstate = _PyThreadState_GET(); |
277 | 113k | _PyErr_SetNone(tstate, exception); |
278 | 113k | } |
279 | | |
280 | | |
281 | | void |
282 | | _PyErr_SetString(PyThreadState *tstate, PyObject *exception, |
283 | | const char *string) |
284 | 35.2k | { |
285 | 35.2k | PyObject *value = PyUnicode_FromString(string); |
286 | 35.2k | if (value != NULL) { |
287 | 35.2k | _PyErr_SetObject(tstate, exception, value); |
288 | 35.2k | Py_DECREF(value); |
289 | 35.2k | } |
290 | 35.2k | } |
291 | | |
292 | | void |
293 | | PyErr_SetString(PyObject *exception, const char *string) |
294 | 35.2k | { |
295 | 35.2k | PyThreadState *tstate = _PyThreadState_GET(); |
296 | 35.2k | _PyErr_SetString(tstate, exception, string); |
297 | 35.2k | } |
298 | | |
299 | | void |
300 | | _PyErr_SetLocaleString(PyObject *exception, const char *string) |
301 | 0 | { |
302 | 0 | PyObject *value = PyUnicode_DecodeLocale(string, "surrogateescape"); |
303 | 0 | if (value != NULL) { |
304 | 0 | PyErr_SetObject(exception, value); |
305 | 0 | Py_DECREF(value); |
306 | 0 | } |
307 | 0 | } |
308 | | |
309 | | PyObject* _Py_HOT_FUNCTION |
310 | | PyErr_Occurred(void) |
311 | 250M | { |
312 | | /* The caller must hold a thread state. */ |
313 | 250M | _Py_AssertHoldsTstate(); |
314 | | |
315 | 250M | PyThreadState *tstate = _PyThreadState_GET(); |
316 | 250M | return _PyErr_Occurred(tstate); |
317 | 250M | } |
318 | | |
319 | | |
320 | | int |
321 | | PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) |
322 | 33.5M | { |
323 | 33.5M | if (err == NULL || exc == NULL) { |
324 | | /* maybe caused by "import exceptions" that failed early on */ |
325 | 1.12M | return 0; |
326 | 1.12M | } |
327 | 32.4M | if (PyTuple_Check(exc)) { |
328 | 156k | Py_ssize_t i, n; |
329 | 156k | n = PyTuple_Size(exc); |
330 | 162k | for (i = 0; i < n; i++) { |
331 | | /* Test recursively */ |
332 | 161k | if (PyErr_GivenExceptionMatches( |
333 | 161k | err, PyTuple_GET_ITEM(exc, i))) |
334 | 154k | { |
335 | 154k | return 1; |
336 | 154k | } |
337 | 161k | } |
338 | 1.69k | return 0; |
339 | 156k | } |
340 | | /* err might be an instance, so check its class. */ |
341 | 32.2M | if (PyExceptionInstance_Check(err)) |
342 | 20.0M | err = PyExceptionInstance_Class(err); |
343 | | |
344 | 32.2M | if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) { |
345 | 32.2M | return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc); |
346 | 32.2M | } |
347 | | |
348 | 0 | return err == exc; |
349 | 32.2M | } |
350 | | |
351 | | |
352 | | int |
353 | | _PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc) |
354 | 13.3M | { |
355 | 13.3M | return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); |
356 | 13.3M | } |
357 | | |
358 | | |
359 | | int |
360 | | PyErr_ExceptionMatches(PyObject *exc) |
361 | 598k | { |
362 | 598k | PyThreadState *tstate = _PyThreadState_GET(); |
363 | 598k | return _PyErr_ExceptionMatches(tstate, exc); |
364 | 598k | } |
365 | | |
366 | | |
367 | | #ifndef Py_NORMALIZE_RECURSION_LIMIT |
368 | 0 | #define Py_NORMALIZE_RECURSION_LIMIT 32 |
369 | | #endif |
370 | | |
371 | | /* Used in many places to normalize a raised exception, including in |
372 | | eval_code2(), do_raise(), and PyErr_Print() |
373 | | |
374 | | XXX: should PyErr_NormalizeException() also call |
375 | | PyException_SetTraceback() with the resulting value and tb? |
376 | | */ |
377 | | void |
378 | | _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, |
379 | | PyObject **val, PyObject **tb) |
380 | 0 | { |
381 | 0 | int recursion_depth = 0; |
382 | 0 | tstate->recursion_headroom++; |
383 | 0 | PyObject *type, *value, *initial_tb; |
384 | |
|
385 | 0 | restart: |
386 | 0 | type = *exc; |
387 | 0 | if (type == NULL) { |
388 | | /* There was no exception, so nothing to do. */ |
389 | 0 | tstate->recursion_headroom--; |
390 | 0 | return; |
391 | 0 | } |
392 | | |
393 | 0 | value = *val; |
394 | | /* If PyErr_SetNone() was used, the value will have been actually |
395 | | set to NULL. |
396 | | */ |
397 | 0 | if (!value) { |
398 | 0 | value = Py_NewRef(Py_None); |
399 | 0 | } |
400 | | |
401 | | /* Normalize the exception so that if the type is a class, the |
402 | | value will be an instance. |
403 | | */ |
404 | 0 | if (PyExceptionClass_Check(type)) { |
405 | 0 | PyObject *inclass = NULL; |
406 | 0 | int is_subclass = 0; |
407 | |
|
408 | 0 | if (PyExceptionInstance_Check(value)) { |
409 | 0 | inclass = PyExceptionInstance_Class(value); |
410 | 0 | is_subclass = PyObject_IsSubclass(inclass, type); |
411 | 0 | if (is_subclass < 0) { |
412 | 0 | goto error; |
413 | 0 | } |
414 | 0 | } |
415 | | |
416 | | /* If the value was not an instance, or is not an instance |
417 | | whose class is (or is derived from) type, then use the |
418 | | value as an argument to instantiation of the type |
419 | | class. |
420 | | */ |
421 | 0 | if (!is_subclass) { |
422 | 0 | PyObject *fixed_value = _PyErr_CreateException(type, value); |
423 | 0 | if (fixed_value == NULL) { |
424 | 0 | goto error; |
425 | 0 | } |
426 | 0 | Py_SETREF(value, fixed_value); |
427 | 0 | } |
428 | | /* If the class of the instance doesn't exactly match the |
429 | | class of the type, believe the instance. |
430 | | */ |
431 | 0 | else if (inclass != type) { |
432 | 0 | Py_SETREF(type, Py_NewRef(inclass)); |
433 | 0 | } |
434 | 0 | } |
435 | 0 | *exc = type; |
436 | 0 | *val = value; |
437 | 0 | tstate->recursion_headroom--; |
438 | 0 | return; |
439 | | |
440 | 0 | error: |
441 | 0 | Py_DECREF(type); |
442 | 0 | Py_DECREF(value); |
443 | 0 | recursion_depth++; |
444 | 0 | if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) { |
445 | 0 | _PyErr_SetString(tstate, PyExc_RecursionError, |
446 | 0 | "maximum recursion depth exceeded " |
447 | 0 | "while normalizing an exception"); |
448 | 0 | } |
449 | | /* If the new exception doesn't set a traceback and the old |
450 | | exception had a traceback, use the old traceback for the |
451 | | new exception. It's better than nothing. |
452 | | */ |
453 | 0 | initial_tb = *tb; |
454 | 0 | _PyErr_Fetch(tstate, exc, val, tb); |
455 | 0 | assert(*exc != NULL); |
456 | 0 | if (initial_tb != NULL) { |
457 | 0 | if (*tb == NULL) |
458 | 0 | *tb = initial_tb; |
459 | 0 | else |
460 | 0 | Py_DECREF(initial_tb); |
461 | 0 | } |
462 | | /* Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded, and the |
463 | | corresponding RecursionError could not be normalized, and the |
464 | | MemoryError raised when normalize this RecursionError could not be |
465 | | normalized. */ |
466 | 0 | if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) { |
467 | 0 | if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) { |
468 | 0 | Py_FatalError("Cannot recover from MemoryErrors " |
469 | 0 | "while normalizing exceptions."); |
470 | 0 | } |
471 | 0 | else { |
472 | 0 | Py_FatalError("Cannot recover from the recursive normalization " |
473 | 0 | "of an exception."); |
474 | 0 | } |
475 | 0 | } |
476 | 0 | goto restart; |
477 | 0 | } |
478 | | |
479 | | |
480 | | void |
481 | | PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) |
482 | 0 | { |
483 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
484 | 0 | _PyErr_NormalizeException(tstate, exc, val, tb); |
485 | 0 | } |
486 | | |
487 | | |
488 | | PyObject * |
489 | 99.1M | _PyErr_GetRaisedException(PyThreadState *tstate) { |
490 | 99.1M | PyObject *exc = tstate->current_exception; |
491 | 99.1M | tstate->current_exception = NULL; |
492 | 99.1M | return exc; |
493 | 99.1M | } |
494 | | |
495 | | PyObject * |
496 | | PyErr_GetRaisedException(void) |
497 | 78.4M | { |
498 | 78.4M | PyThreadState *tstate = _PyThreadState_GET(); |
499 | 78.4M | return _PyErr_GetRaisedException(tstate); |
500 | 78.4M | } |
501 | | |
502 | | void |
503 | | _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, |
504 | | PyObject **p_traceback) |
505 | 11.7k | { |
506 | 11.7k | PyObject *exc = _PyErr_GetRaisedException(tstate); |
507 | 11.7k | *p_value = exc; |
508 | 11.7k | if (exc == NULL) { |
509 | 0 | *p_type = NULL; |
510 | 0 | *p_traceback = NULL; |
511 | 0 | } |
512 | 11.7k | else { |
513 | 11.7k | *p_type = Py_NewRef(Py_TYPE(exc)); |
514 | 11.7k | *p_traceback = PyException_GetTraceback(exc); |
515 | 11.7k | } |
516 | 11.7k | } |
517 | | |
518 | | |
519 | | void |
520 | | PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) |
521 | 11.7k | { |
522 | 11.7k | PyThreadState *tstate = _PyThreadState_GET(); |
523 | 11.7k | _PyErr_Fetch(tstate, p_type, p_value, p_traceback); |
524 | 11.7k | } |
525 | | |
526 | | |
527 | | void |
528 | | _PyErr_Clear(PyThreadState *tstate) |
529 | 42.4M | { |
530 | 42.4M | _PyErr_Restore(tstate, NULL, NULL, NULL); |
531 | 42.4M | } |
532 | | |
533 | | |
534 | | void |
535 | | PyErr_Clear(void) |
536 | 18.9k | { |
537 | 18.9k | PyThreadState *tstate = _PyThreadState_GET(); |
538 | 18.9k | _PyErr_Clear(tstate); |
539 | 18.9k | } |
540 | | |
541 | | static PyObject* |
542 | | get_exc_type(PyObject *exc_value) /* returns a strong ref */ |
543 | 0 | { |
544 | 0 | if (exc_value == NULL || exc_value == Py_None) { |
545 | 0 | return Py_None; |
546 | 0 | } |
547 | 0 | else { |
548 | 0 | assert(PyExceptionInstance_Check(exc_value)); |
549 | 0 | PyObject *type = PyExceptionInstance_Class(exc_value); |
550 | 0 | assert(type != NULL); |
551 | 0 | return Py_NewRef(type); |
552 | 0 | } |
553 | 0 | } |
554 | | |
555 | | static PyObject* |
556 | | get_exc_traceback(PyObject *exc_value) /* returns a strong ref */ |
557 | 0 | { |
558 | 0 | if (exc_value == NULL || exc_value == Py_None) { |
559 | 0 | return Py_None; |
560 | 0 | } |
561 | 0 | else { |
562 | 0 | assert(PyExceptionInstance_Check(exc_value)); |
563 | 0 | PyObject *tb = PyException_GetTraceback(exc_value); |
564 | 0 | return tb ? tb : Py_None; |
565 | 0 | } |
566 | 0 | } |
567 | | |
568 | | void |
569 | | _PyErr_GetExcInfo(PyThreadState *tstate, |
570 | | PyObject **p_type, PyObject **p_value, PyObject **p_traceback) |
571 | 0 | { |
572 | 0 | _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); |
573 | |
|
574 | 0 | *p_type = get_exc_type(exc_info->exc_value); |
575 | 0 | *p_value = Py_XNewRef(exc_info->exc_value); |
576 | 0 | *p_traceback = get_exc_traceback(exc_info->exc_value); |
577 | 0 | } |
578 | | |
579 | | PyObject* |
580 | | _PyErr_GetHandledException(PyThreadState *tstate) |
581 | 0 | { |
582 | 0 | _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); |
583 | 0 | PyObject *exc = exc_info->exc_value; |
584 | 0 | if (exc == NULL || exc == Py_None) { |
585 | 0 | return NULL; |
586 | 0 | } |
587 | 0 | return Py_NewRef(exc); |
588 | 0 | } |
589 | | |
590 | | PyObject* |
591 | | PyErr_GetHandledException(void) |
592 | 0 | { |
593 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
594 | 0 | return _PyErr_GetHandledException(tstate); |
595 | 0 | } |
596 | | |
597 | | void |
598 | | _PyErr_SetHandledException(PyThreadState *tstate, PyObject *exc) |
599 | 0 | { |
600 | 0 | Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc == Py_None ? NULL : exc)); |
601 | 0 | } |
602 | | |
603 | | void |
604 | | PyErr_SetHandledException(PyObject *exc) |
605 | 0 | { |
606 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
607 | 0 | _PyErr_SetHandledException(tstate, exc); |
608 | 0 | } |
609 | | |
610 | | void |
611 | | PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) |
612 | 0 | { |
613 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
614 | 0 | _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback); |
615 | 0 | } |
616 | | |
617 | | void |
618 | | PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) |
619 | 0 | { |
620 | 0 | PyErr_SetHandledException(value); |
621 | 0 | Py_XDECREF(value); |
622 | | /* These args are no longer used, but we still need to steal a ref */ |
623 | 0 | Py_XDECREF(type); |
624 | 0 | Py_XDECREF(traceback); |
625 | 0 | } |
626 | | |
627 | | |
628 | | PyObject* |
629 | | _PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info) |
630 | 0 | { |
631 | 0 | PyObject *exc_value = err_info->exc_value; |
632 | |
|
633 | 0 | assert(exc_value == NULL || |
634 | 0 | exc_value == Py_None || |
635 | 0 | PyExceptionInstance_Check(exc_value)); |
636 | |
|
637 | 0 | PyObject *ret = PyTuple_New(3); |
638 | 0 | if (ret == NULL) { |
639 | 0 | return NULL; |
640 | 0 | } |
641 | | |
642 | 0 | PyObject *exc_type = get_exc_type(exc_value); |
643 | 0 | PyObject *exc_traceback = get_exc_traceback(exc_value); |
644 | |
|
645 | 0 | PyTuple_SET_ITEM(ret, 0, exc_type ? exc_type : Py_None); |
646 | 0 | PyTuple_SET_ITEM(ret, 1, exc_value ? Py_NewRef(exc_value) : Py_None); |
647 | 0 | PyTuple_SET_ITEM(ret, 2, exc_traceback ? exc_traceback : Py_None); |
648 | |
|
649 | 0 | return ret; |
650 | 0 | } |
651 | | |
652 | | |
653 | | /* Like PyErr_Restore(), but if an exception is already set, |
654 | | set the context associated with it. |
655 | | |
656 | | The caller is responsible for ensuring that this call won't create |
657 | | any cycles in the exception context chain. */ |
658 | | void |
659 | | _PyErr_ChainExceptions(PyObject *typ, PyObject *val, PyObject *tb) |
660 | 0 | { |
661 | 0 | if (typ == NULL) |
662 | 0 | return; |
663 | | |
664 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
665 | |
|
666 | 0 | if (!PyExceptionClass_Check(typ)) { |
667 | 0 | _PyErr_Format(tstate, PyExc_SystemError, |
668 | 0 | "_PyErr_ChainExceptions: " |
669 | 0 | "exception %R is not a BaseException subclass", |
670 | 0 | typ); |
671 | 0 | return; |
672 | 0 | } |
673 | | |
674 | 0 | if (_PyErr_Occurred(tstate)) { |
675 | 0 | _PyErr_NormalizeException(tstate, &typ, &val, &tb); |
676 | 0 | if (tb != NULL) { |
677 | 0 | PyException_SetTraceback(val, tb); |
678 | 0 | Py_DECREF(tb); |
679 | 0 | } |
680 | 0 | Py_DECREF(typ); |
681 | 0 | PyObject *exc2 = _PyErr_GetRaisedException(tstate); |
682 | 0 | PyException_SetContext(exc2, val); |
683 | 0 | _PyErr_SetRaisedException(tstate, exc2); |
684 | 0 | } |
685 | 0 | else { |
686 | 0 | _PyErr_Restore(tstate, typ, val, tb); |
687 | 0 | } |
688 | 0 | } |
689 | | |
690 | | /* Like PyErr_SetRaisedException(), but if an exception is already set, |
691 | | set the context associated with it. |
692 | | |
693 | | The caller is responsible for ensuring that this call won't create |
694 | | any cycles in the exception context chain. */ |
695 | | void |
696 | | _PyErr_ChainExceptions1Tstate(PyThreadState *tstate, PyObject *exc) |
697 | 11.0k | { |
698 | 11.0k | if (exc == NULL) { |
699 | 11.0k | return; |
700 | 11.0k | } |
701 | 0 | if (_PyErr_Occurred(tstate)) { |
702 | 0 | PyObject *exc2 = _PyErr_GetRaisedException(tstate); |
703 | 0 | PyException_SetContext(exc2, exc); |
704 | 0 | _PyErr_SetRaisedException(tstate, exc2); |
705 | 0 | } |
706 | 0 | else { |
707 | 0 | _PyErr_SetRaisedException(tstate, exc); |
708 | 0 | } |
709 | 0 | } |
710 | | |
711 | | void |
712 | | _PyErr_ChainExceptions1(PyObject *exc) |
713 | 11.0k | { |
714 | 11.0k | PyThreadState *tstate = _PyThreadState_GET(); |
715 | 11.0k | _PyErr_ChainExceptions1Tstate(tstate, exc); |
716 | 11.0k | } |
717 | | |
718 | | /* If the current thread is handling an exception (exc_info is ), set this |
719 | | exception as the context of the current raised exception. |
720 | | |
721 | | This function can only be called when _PyErr_Occurred() is true. |
722 | | Also, this function won't create any cycles in the exception context |
723 | | chain to the extent that _PyErr_SetObject ensures this. */ |
724 | | void |
725 | | _PyErr_ChainStackItem(void) |
726 | 2.92k | { |
727 | 2.92k | PyThreadState *tstate = _PyThreadState_GET(); |
728 | 2.92k | assert(_PyErr_Occurred(tstate)); |
729 | | |
730 | 2.92k | _PyErr_StackItem *exc_info = tstate->exc_info; |
731 | 2.92k | if (exc_info->exc_value == NULL || exc_info->exc_value == Py_None) { |
732 | 2.92k | return; |
733 | 2.92k | } |
734 | | |
735 | 0 | PyObject *exc = _PyErr_GetRaisedException(tstate); |
736 | | |
737 | | /* _PyErr_SetObject sets the context from PyThreadState. */ |
738 | 0 | _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(exc), exc); |
739 | 0 | Py_DECREF(exc); // since _PyErr_Occurred was true |
740 | 0 | } |
741 | | |
742 | | static PyObject * |
743 | | _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, |
744 | | const char *format, va_list vargs) |
745 | 0 | { |
746 | 0 | assert(_PyErr_Occurred(tstate)); |
747 | 0 | PyObject *exc = _PyErr_GetRaisedException(tstate); |
748 | 0 | assert(!_PyErr_Occurred(tstate)); |
749 | 0 | _PyErr_FormatV(tstate, exception, format, vargs); |
750 | 0 | PyObject *exc2 = _PyErr_GetRaisedException(tstate); |
751 | 0 | PyException_SetCause(exc2, Py_NewRef(exc)); |
752 | 0 | PyException_SetContext(exc2, Py_NewRef(exc)); |
753 | 0 | Py_DECREF(exc); |
754 | 0 | _PyErr_SetRaisedException(tstate, exc2); |
755 | 0 | return NULL; |
756 | 0 | } |
757 | | |
758 | | PyObject * |
759 | | _PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception, |
760 | | const char *format, ...) |
761 | 0 | { |
762 | 0 | va_list vargs; |
763 | 0 | va_start(vargs, format); |
764 | 0 | _PyErr_FormatVFromCause(tstate, exception, format, vargs); |
765 | 0 | va_end(vargs); |
766 | 0 | return NULL; |
767 | 0 | } |
768 | | |
769 | | PyObject * |
770 | | _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) |
771 | 0 | { |
772 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
773 | 0 | va_list vargs; |
774 | 0 | va_start(vargs, format); |
775 | 0 | _PyErr_FormatVFromCause(tstate, exception, format, vargs); |
776 | 0 | va_end(vargs); |
777 | 0 | return NULL; |
778 | 0 | } |
779 | | |
780 | | /* Convenience functions to set a type error exception and return 0 */ |
781 | | |
782 | | int |
783 | | PyErr_BadArgument(void) |
784 | 0 | { |
785 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
786 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
787 | 0 | "bad argument type for built-in operation"); |
788 | 0 | return 0; |
789 | 0 | } |
790 | | |
791 | | PyObject * |
792 | | PyErr_NoMemory(void) |
793 | 0 | { |
794 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
795 | 0 | return _PyErr_NoMemory(tstate); |
796 | 0 | } |
797 | | |
798 | | PyObject * |
799 | | PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) |
800 | 12.1k | { |
801 | 12.1k | return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL); |
802 | 12.1k | } |
803 | | |
804 | | PyObject * |
805 | | PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) |
806 | 12.2k | { |
807 | 12.2k | PyThreadState *tstate = _PyThreadState_GET(); |
808 | 12.2k | PyObject *message; |
809 | 12.2k | PyObject *v, *args; |
810 | 12.2k | int i = errno; |
811 | | #ifdef MS_WINDOWS |
812 | | WCHAR *s_buf = NULL; |
813 | | #endif /* Unix/Windows */ |
814 | | |
815 | 12.2k | #ifdef EINTR |
816 | 12.2k | if (i == EINTR && PyErr_CheckSignals()) |
817 | 0 | return NULL; |
818 | 12.2k | #endif |
819 | | |
820 | 12.2k | #ifndef MS_WINDOWS |
821 | 12.2k | if (i != 0) { |
822 | 12.2k | const char *s = strerror(i); |
823 | 12.2k | message = PyUnicode_DecodeLocale(s, "surrogateescape"); |
824 | 12.2k | } |
825 | 0 | else { |
826 | | /* Sometimes errno didn't get set */ |
827 | 0 | message = PyUnicode_FromString("Error"); |
828 | 0 | } |
829 | | #else |
830 | | if (i == 0) |
831 | | message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */ |
832 | | else |
833 | | { |
834 | | /* Note that the Win32 errors do not lineup with the |
835 | | errno error. So if the error is in the MSVC error |
836 | | table, we use it, otherwise we assume it really _is_ |
837 | | a Win32 error code |
838 | | */ |
839 | | if (i > 0 && i < _sys_nerr) { |
840 | | message = PyUnicode_FromString(_sys_errlist[i]); |
841 | | } |
842 | | else { |
843 | | int len = FormatMessageW( |
844 | | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
845 | | FORMAT_MESSAGE_FROM_SYSTEM | |
846 | | FORMAT_MESSAGE_IGNORE_INSERTS, |
847 | | NULL, /* no message source */ |
848 | | i, |
849 | | MAKELANGID(LANG_NEUTRAL, |
850 | | SUBLANG_DEFAULT), |
851 | | /* Default language */ |
852 | | (LPWSTR) &s_buf, |
853 | | 0, /* size not used */ |
854 | | NULL); /* no args */ |
855 | | if (len==0) { |
856 | | /* Only ever seen this in out-of-mem |
857 | | situations */ |
858 | | s_buf = NULL; |
859 | | message = PyUnicode_FromFormat("Windows Error 0x%x", i); |
860 | | } else { |
861 | | /* remove trailing cr/lf and dots */ |
862 | | while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.')) |
863 | | s_buf[--len] = L'\0'; |
864 | | message = PyUnicode_FromWideChar(s_buf, len); |
865 | | } |
866 | | } |
867 | | } |
868 | | #endif /* Unix/Windows */ |
869 | | |
870 | 12.2k | if (message == NULL) |
871 | 0 | { |
872 | | #ifdef MS_WINDOWS |
873 | | LocalFree(s_buf); |
874 | | #endif |
875 | 0 | return NULL; |
876 | 0 | } |
877 | | |
878 | 12.2k | if (filenameObject != NULL) { |
879 | 12.1k | if (filenameObject2 != NULL) |
880 | 0 | args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2); |
881 | 12.1k | else |
882 | 12.1k | args = Py_BuildValue("(iOO)", i, message, filenameObject); |
883 | 12.1k | } else { |
884 | 80 | assert(filenameObject2 == NULL); |
885 | 80 | args = Py_BuildValue("(iO)", i, message); |
886 | 80 | } |
887 | 12.2k | Py_DECREF(message); |
888 | | |
889 | 12.2k | if (args != NULL) { |
890 | 12.2k | v = PyObject_Call(exc, args, NULL); |
891 | 12.2k | Py_DECREF(args); |
892 | 12.2k | if (v != NULL) { |
893 | 12.2k | _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); |
894 | 12.2k | Py_DECREF(v); |
895 | 12.2k | } |
896 | 12.2k | } |
897 | | #ifdef MS_WINDOWS |
898 | | LocalFree(s_buf); |
899 | | #endif |
900 | 12.2k | return NULL; |
901 | 12.2k | } |
902 | | |
903 | | PyObject * |
904 | | PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) |
905 | 0 | { |
906 | 0 | PyObject *name = NULL; |
907 | 0 | if (filename) { |
908 | 0 | int i = errno; |
909 | 0 | name = PyUnicode_DecodeFSDefault(filename); |
910 | 0 | if (name == NULL) { |
911 | 0 | return NULL; |
912 | 0 | } |
913 | 0 | errno = i; |
914 | 0 | } |
915 | 0 | PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); |
916 | 0 | Py_XDECREF(name); |
917 | 0 | return result; |
918 | 0 | } |
919 | | |
920 | | PyObject * |
921 | | PyErr_SetFromErrno(PyObject *exc) |
922 | 80 | { |
923 | 80 | return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL); |
924 | 80 | } |
925 | | |
926 | | #ifdef MS_WINDOWS |
927 | | /* Windows specific error code handling */ |
928 | | PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( |
929 | | PyObject *exc, |
930 | | int ierr, |
931 | | PyObject *filenameObject) |
932 | | { |
933 | | return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, |
934 | | filenameObject, NULL); |
935 | | } |
936 | | |
937 | | PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( |
938 | | PyObject *exc, |
939 | | int ierr, |
940 | | PyObject *filenameObject, |
941 | | PyObject *filenameObject2) |
942 | | { |
943 | | PyThreadState *tstate = _PyThreadState_GET(); |
944 | | int len; |
945 | | WCHAR *s_buf = NULL; /* Free via LocalFree */ |
946 | | PyObject *message; |
947 | | PyObject *args, *v; |
948 | | |
949 | | DWORD err = (DWORD)ierr; |
950 | | if (err==0) { |
951 | | err = GetLastError(); |
952 | | } |
953 | | |
954 | | len = FormatMessageW( |
955 | | /* Error API error */ |
956 | | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
957 | | FORMAT_MESSAGE_FROM_SYSTEM | |
958 | | FORMAT_MESSAGE_IGNORE_INSERTS, |
959 | | NULL, /* no message source */ |
960 | | err, |
961 | | MAKELANGID(LANG_NEUTRAL, |
962 | | SUBLANG_DEFAULT), /* Default language */ |
963 | | (LPWSTR) &s_buf, |
964 | | 0, /* size not used */ |
965 | | NULL); /* no args */ |
966 | | if (len==0) { |
967 | | /* Only seen this in out of mem situations */ |
968 | | message = PyUnicode_FromFormat("Windows Error 0x%x", err); |
969 | | s_buf = NULL; |
970 | | } else { |
971 | | /* remove trailing cr/lf and dots */ |
972 | | while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.')) |
973 | | s_buf[--len] = L'\0'; |
974 | | message = PyUnicode_FromWideChar(s_buf, len); |
975 | | } |
976 | | |
977 | | if (message == NULL) |
978 | | { |
979 | | LocalFree(s_buf); |
980 | | return NULL; |
981 | | } |
982 | | |
983 | | if (filenameObject == NULL) { |
984 | | assert(filenameObject2 == NULL); |
985 | | filenameObject = filenameObject2 = Py_None; |
986 | | } |
987 | | else if (filenameObject2 == NULL) |
988 | | filenameObject2 = Py_None; |
989 | | /* This is the constructor signature for OSError. |
990 | | The POSIX translation will be figured out by the constructor. */ |
991 | | args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2); |
992 | | Py_DECREF(message); |
993 | | |
994 | | if (args != NULL) { |
995 | | v = PyObject_Call(exc, args, NULL); |
996 | | Py_DECREF(args); |
997 | | if (v != NULL) { |
998 | | _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); |
999 | | Py_DECREF(v); |
1000 | | } |
1001 | | } |
1002 | | LocalFree(s_buf); |
1003 | | return NULL; |
1004 | | } |
1005 | | |
1006 | | PyObject *PyErr_SetExcFromWindowsErrWithFilename( |
1007 | | PyObject *exc, |
1008 | | int ierr, |
1009 | | const char *filename) |
1010 | | { |
1011 | | PyObject *name = NULL; |
1012 | | if (filename) { |
1013 | | if ((DWORD)ierr == 0) { |
1014 | | ierr = (int)GetLastError(); |
1015 | | } |
1016 | | name = PyUnicode_DecodeFSDefault(filename); |
1017 | | if (name == NULL) { |
1018 | | return NULL; |
1019 | | } |
1020 | | } |
1021 | | PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, |
1022 | | ierr, |
1023 | | name, |
1024 | | NULL); |
1025 | | Py_XDECREF(name); |
1026 | | return ret; |
1027 | | } |
1028 | | |
1029 | | PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr) |
1030 | | { |
1031 | | return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL); |
1032 | | } |
1033 | | |
1034 | | PyObject *PyErr_SetFromWindowsErr(int ierr) |
1035 | | { |
1036 | | return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError, |
1037 | | ierr, NULL); |
1038 | | } |
1039 | | |
1040 | | PyObject *PyErr_SetFromWindowsErrWithFilename( |
1041 | | int ierr, |
1042 | | const char *filename) |
1043 | | { |
1044 | | PyObject *name = NULL; |
1045 | | if (filename) { |
1046 | | if ((DWORD)ierr == 0) { |
1047 | | ierr = (int)GetLastError(); |
1048 | | } |
1049 | | name = PyUnicode_DecodeFSDefault(filename); |
1050 | | if (name == NULL) { |
1051 | | return NULL; |
1052 | | } |
1053 | | } |
1054 | | PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( |
1055 | | PyExc_OSError, |
1056 | | ierr, name, NULL); |
1057 | | Py_XDECREF(name); |
1058 | | return result; |
1059 | | } |
1060 | | |
1061 | | #endif /* MS_WINDOWS */ |
1062 | | |
1063 | | static PyObject * |
1064 | | new_importerror( |
1065 | | PyThreadState *tstate, PyObject *exctype, PyObject *msg, |
1066 | | PyObject *name, PyObject *path, PyObject* from_name) |
1067 | 18 | { |
1068 | 18 | PyObject *exc = NULL; |
1069 | 18 | PyObject *kwargs = NULL; |
1070 | | |
1071 | 18 | int issubclass = PyObject_IsSubclass(exctype, PyExc_ImportError); |
1072 | 18 | if (issubclass < 0) { |
1073 | 0 | return NULL; |
1074 | 0 | } |
1075 | 18 | else if (!issubclass) { |
1076 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
1077 | 0 | "expected a subclass of ImportError"); |
1078 | 0 | return NULL; |
1079 | 0 | } |
1080 | | |
1081 | 18 | if (msg == NULL) { |
1082 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
1083 | 0 | "expected a message argument"); |
1084 | 0 | return NULL; |
1085 | 0 | } |
1086 | | |
1087 | 18 | if (name == NULL) { |
1088 | 0 | name = Py_None; |
1089 | 0 | } |
1090 | 18 | if (path == NULL) { |
1091 | 10 | path = Py_None; |
1092 | 10 | } |
1093 | 18 | if (from_name == NULL) { |
1094 | 0 | from_name = Py_None; |
1095 | 0 | } |
1096 | | |
1097 | 18 | kwargs = PyDict_New(); |
1098 | 18 | if (kwargs == NULL) { |
1099 | 0 | return NULL; |
1100 | 0 | } |
1101 | 18 | if (PyDict_SetItemString(kwargs, "name", name) < 0) { |
1102 | 0 | goto finally; |
1103 | 0 | } |
1104 | 18 | if (PyDict_SetItemString(kwargs, "path", path) < 0) { |
1105 | 0 | goto finally; |
1106 | 0 | } |
1107 | 18 | if (PyDict_SetItemString(kwargs, "name_from", from_name) < 0) { |
1108 | 0 | goto finally; |
1109 | 0 | } |
1110 | 18 | exc = PyObject_VectorcallDict(exctype, &msg, 1, kwargs); |
1111 | | |
1112 | 18 | finally: |
1113 | 18 | Py_DECREF(kwargs); |
1114 | 18 | return exc; |
1115 | 18 | } |
1116 | | |
1117 | | static PyObject * |
1118 | | _PyErr_SetImportErrorSubclassWithNameFrom( |
1119 | | PyObject *exception, PyObject *msg, |
1120 | | PyObject *name, PyObject *path, PyObject* from_name) |
1121 | 18 | { |
1122 | 18 | PyThreadState *tstate = _PyThreadState_GET(); |
1123 | 18 | PyObject *error = new_importerror( |
1124 | 18 | tstate, exception, msg, name, path, from_name); |
1125 | 18 | if (error != NULL) { |
1126 | 18 | _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error); |
1127 | 18 | Py_DECREF(error); |
1128 | 18 | } |
1129 | 18 | return NULL; |
1130 | 18 | } |
1131 | | |
1132 | | |
1133 | | PyObject * |
1134 | | PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, |
1135 | | PyObject *name, PyObject *path) |
1136 | 0 | { |
1137 | 0 | return _PyErr_SetImportErrorSubclassWithNameFrom(exception, msg, name, path, NULL); |
1138 | 0 | } |
1139 | | |
1140 | | PyObject * |
1141 | | _PyErr_SetImportErrorWithNameFrom(PyObject *msg, PyObject *name, PyObject *path, PyObject* from_name) |
1142 | 18 | { |
1143 | 18 | return _PyErr_SetImportErrorSubclassWithNameFrom(PyExc_ImportError, msg, name, path, from_name); |
1144 | 18 | } |
1145 | | |
1146 | | PyObject * |
1147 | | PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) |
1148 | 0 | { |
1149 | 0 | return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path); |
1150 | 0 | } |
1151 | | |
1152 | | int |
1153 | | _PyErr_SetModuleNotFoundError(PyObject *name) |
1154 | 0 | { |
1155 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
1156 | 0 | if (name == NULL) { |
1157 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, "expected a name argument"); |
1158 | 0 | return -1; |
1159 | 0 | } |
1160 | 0 | PyObject *msg = PyUnicode_FromFormat("%S module not found", name); |
1161 | 0 | if (msg == NULL) { |
1162 | 0 | return -1; |
1163 | 0 | } |
1164 | 0 | PyObject *exctype = PyExc_ModuleNotFoundError; |
1165 | 0 | PyObject *exc = new_importerror(tstate, exctype, msg, name, NULL, NULL); |
1166 | 0 | Py_DECREF(msg); |
1167 | 0 | if (exc == NULL) { |
1168 | 0 | return -1; |
1169 | 0 | } |
1170 | 0 | _PyErr_SetObject(tstate, exctype, exc); |
1171 | 0 | Py_DECREF(exc); |
1172 | 0 | return 0; |
1173 | 0 | } |
1174 | | |
1175 | | void |
1176 | | _PyErr_BadInternalCall(const char *filename, int lineno) |
1177 | 1 | { |
1178 | 1 | PyThreadState *tstate = _PyThreadState_GET(); |
1179 | 1 | _PyErr_Format(tstate, PyExc_SystemError, |
1180 | 1 | "%s:%d: bad argument to internal function", |
1181 | 1 | filename, lineno); |
1182 | 1 | } |
1183 | | |
1184 | | /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can |
1185 | | export the entry point for existing object code: */ |
1186 | | #undef PyErr_BadInternalCall |
1187 | | void |
1188 | | PyErr_BadInternalCall(void) |
1189 | 0 | { |
1190 | 0 | assert(0 && "bad argument to internal function"); |
1191 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
1192 | 0 | _PyErr_SetString(tstate, PyExc_SystemError, |
1193 | 0 | "bad argument to internal function"); |
1194 | 0 | } |
1195 | | #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) |
1196 | | |
1197 | | |
1198 | | PyObject * |
1199 | | _PyErr_FormatV(PyThreadState *tstate, PyObject *exception, |
1200 | | const char *format, va_list vargs) |
1201 | 15.0M | { |
1202 | 15.0M | PyObject* string; |
1203 | | |
1204 | | /* Issue #23571: PyUnicode_FromFormatV() must not be called with an |
1205 | | exception set, it calls arbitrary Python code like PyObject_Repr() */ |
1206 | 15.0M | _PyErr_Clear(tstate); |
1207 | | |
1208 | 15.0M | string = PyUnicode_FromFormatV(format, vargs); |
1209 | 15.0M | if (string != NULL) { |
1210 | 15.0M | _PyErr_SetObject(tstate, exception, string); |
1211 | 15.0M | Py_DECREF(string); |
1212 | 15.0M | } |
1213 | 15.0M | return NULL; |
1214 | 15.0M | } |
1215 | | |
1216 | | |
1217 | | PyObject * |
1218 | | PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) |
1219 | 0 | { |
1220 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
1221 | 0 | return _PyErr_FormatV(tstate, exception, format, vargs); |
1222 | 0 | } |
1223 | | |
1224 | | |
1225 | | PyObject * |
1226 | | _PyErr_Format(PyThreadState *tstate, PyObject *exception, |
1227 | | const char *format, ...) |
1228 | 9.02M | { |
1229 | 9.02M | va_list vargs; |
1230 | 9.02M | va_start(vargs, format); |
1231 | 9.02M | _PyErr_FormatV(tstate, exception, format, vargs); |
1232 | 9.02M | va_end(vargs); |
1233 | 9.02M | return NULL; |
1234 | 9.02M | } |
1235 | | |
1236 | | |
1237 | | PyObject * |
1238 | | PyErr_Format(PyObject *exception, const char *format, ...) |
1239 | 6.02M | { |
1240 | 6.02M | PyThreadState *tstate = _PyThreadState_GET(); |
1241 | 6.02M | va_list vargs; |
1242 | 6.02M | va_start(vargs, format); |
1243 | 6.02M | _PyErr_FormatV(tstate, exception, format, vargs); |
1244 | 6.02M | va_end(vargs); |
1245 | 6.02M | return NULL; |
1246 | 6.02M | } |
1247 | | |
1248 | | |
1249 | | /* Adds a note to the current exception (if any) */ |
1250 | | void |
1251 | | _PyErr_FormatNote(const char *format, ...) |
1252 | 46.2k | { |
1253 | 46.2k | PyObject *exc = PyErr_GetRaisedException(); |
1254 | 46.2k | if (exc == NULL) { |
1255 | 0 | return; |
1256 | 0 | } |
1257 | 46.2k | va_list vargs; |
1258 | 46.2k | va_start(vargs, format); |
1259 | 46.2k | PyObject *note = PyUnicode_FromFormatV(format, vargs); |
1260 | 46.2k | va_end(vargs); |
1261 | 46.2k | if (note == NULL) { |
1262 | 0 | goto error; |
1263 | 0 | } |
1264 | 46.2k | int res = _PyException_AddNote(exc, note); |
1265 | 46.2k | Py_DECREF(note); |
1266 | 46.2k | if (res < 0) { |
1267 | 0 | goto error; |
1268 | 0 | } |
1269 | 46.2k | PyErr_SetRaisedException(exc); |
1270 | 46.2k | return; |
1271 | 0 | error: |
1272 | 0 | _PyErr_ChainExceptions1(exc); |
1273 | 0 | } |
1274 | | |
1275 | | |
1276 | | PyObject * |
1277 | | PyErr_NewException(const char *name, PyObject *base, PyObject *dict) |
1278 | 111 | { |
1279 | 111 | PyThreadState *tstate = _PyThreadState_GET(); |
1280 | 111 | PyObject *modulename = NULL; |
1281 | 111 | PyObject *mydict = NULL; |
1282 | 111 | PyObject *bases = NULL; |
1283 | 111 | PyObject *result = NULL; |
1284 | | |
1285 | 111 | const char *dot = strrchr(name, '.'); |
1286 | 111 | if (dot == NULL) { |
1287 | 0 | _PyErr_SetString(tstate, PyExc_SystemError, |
1288 | 0 | "PyErr_NewException: name must be module.class"); |
1289 | 0 | return NULL; |
1290 | 0 | } |
1291 | 111 | if (base == NULL) { |
1292 | 21 | base = PyExc_Exception; |
1293 | 21 | } |
1294 | 111 | if (dict == NULL) { |
1295 | 87 | dict = mydict = PyDict_New(); |
1296 | 87 | if (dict == NULL) |
1297 | 0 | goto failure; |
1298 | 87 | } |
1299 | | |
1300 | 111 | int r = PyDict_Contains(dict, &_Py_ID(__module__)); |
1301 | 111 | if (r < 0) { |
1302 | 0 | goto failure; |
1303 | 0 | } |
1304 | 111 | if (r == 0) { |
1305 | 111 | modulename = PyUnicode_FromStringAndSize(name, |
1306 | 111 | (Py_ssize_t)(dot-name)); |
1307 | 111 | if (modulename == NULL) |
1308 | 0 | goto failure; |
1309 | 111 | if (PyDict_SetItem(dict, &_Py_ID(__module__), modulename) != 0) |
1310 | 0 | goto failure; |
1311 | 111 | } |
1312 | 111 | if (PyTuple_Check(base)) { |
1313 | 20 | bases = Py_NewRef(base); |
1314 | 91 | } else { |
1315 | 91 | bases = PyTuple_Pack(1, base); |
1316 | 91 | if (bases == NULL) |
1317 | 0 | goto failure; |
1318 | 91 | } |
1319 | | /* Create a real class. */ |
1320 | 111 | result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO", |
1321 | 111 | dot+1, bases, dict); |
1322 | 111 | failure: |
1323 | 111 | Py_XDECREF(bases); |
1324 | 111 | Py_XDECREF(mydict); |
1325 | 111 | Py_XDECREF(modulename); |
1326 | 111 | return result; |
1327 | 111 | } |
1328 | | |
1329 | | |
1330 | | /* Create an exception with docstring */ |
1331 | | PyObject * |
1332 | | PyErr_NewExceptionWithDoc(const char *name, const char *doc, |
1333 | | PyObject *base, PyObject *dict) |
1334 | 24 | { |
1335 | 24 | int result; |
1336 | 24 | PyObject *ret = NULL; |
1337 | 24 | PyObject *mydict = NULL; /* points to the dict only if we create it */ |
1338 | 24 | PyObject *docobj; |
1339 | | |
1340 | 24 | if (dict == NULL) { |
1341 | 24 | dict = mydict = PyDict_New(); |
1342 | 24 | if (dict == NULL) { |
1343 | 0 | return NULL; |
1344 | 0 | } |
1345 | 24 | } |
1346 | | |
1347 | 24 | if (doc != NULL) { |
1348 | 24 | docobj = PyUnicode_FromString(doc); |
1349 | 24 | if (docobj == NULL) |
1350 | 0 | goto failure; |
1351 | 24 | result = PyDict_SetItemString(dict, "__doc__", docobj); |
1352 | 24 | Py_DECREF(docobj); |
1353 | 24 | if (result < 0) |
1354 | 0 | goto failure; |
1355 | 24 | } |
1356 | | |
1357 | 24 | ret = PyErr_NewException(name, base, dict); |
1358 | 24 | failure: |
1359 | 24 | Py_XDECREF(mydict); |
1360 | 24 | return ret; |
1361 | 24 | } |
1362 | | |
1363 | | |
1364 | | PyDoc_STRVAR(UnraisableHookArgs__doc__, |
1365 | | "UnraisableHookArgs\n\ |
1366 | | \n\ |
1367 | | Type used to pass arguments to sys.unraisablehook."); |
1368 | | |
1369 | | static PyTypeObject UnraisableHookArgsType; |
1370 | | |
1371 | | static PyStructSequence_Field UnraisableHookArgs_fields[] = { |
1372 | | {"exc_type", "Exception type"}, |
1373 | | {"exc_value", "Exception value"}, |
1374 | | {"exc_traceback", "Exception traceback"}, |
1375 | | {"err_msg", "Error message"}, |
1376 | | {"object", "Object causing the exception"}, |
1377 | | {0} |
1378 | | }; |
1379 | | |
1380 | | static PyStructSequence_Desc UnraisableHookArgs_desc = { |
1381 | | .name = "UnraisableHookArgs", |
1382 | | .doc = UnraisableHookArgs__doc__, |
1383 | | .fields = UnraisableHookArgs_fields, |
1384 | | .n_in_sequence = 5 |
1385 | | }; |
1386 | | |
1387 | | |
1388 | | PyStatus |
1389 | | _PyErr_InitTypes(PyInterpreterState *interp) |
1390 | 16 | { |
1391 | 16 | if (_PyStructSequence_InitBuiltin(interp, &UnraisableHookArgsType, |
1392 | 16 | &UnraisableHookArgs_desc) < 0) |
1393 | 0 | { |
1394 | 0 | return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); |
1395 | 0 | } |
1396 | 16 | return _PyStatus_OK(); |
1397 | 16 | } |
1398 | | |
1399 | | |
1400 | | void |
1401 | | _PyErr_FiniTypes(PyInterpreterState *interp) |
1402 | 0 | { |
1403 | 0 | _PyStructSequence_FiniBuiltin(interp, &UnraisableHookArgsType); |
1404 | 0 | } |
1405 | | |
1406 | | |
1407 | | static PyObject * |
1408 | | make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, |
1409 | | PyObject *exc_value, PyObject *exc_tb, |
1410 | | PyObject *err_msg, PyObject *obj) |
1411 | 0 | { |
1412 | 0 | PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); |
1413 | 0 | if (args == NULL) { |
1414 | 0 | return NULL; |
1415 | 0 | } |
1416 | | |
1417 | 0 | Py_ssize_t pos = 0; |
1418 | 0 | #define ADD_ITEM(exc_type) \ |
1419 | 0 | do { \ |
1420 | 0 | if (exc_type == NULL) { \ |
1421 | 0 | exc_type = Py_None; \ |
1422 | 0 | } \ |
1423 | 0 | PyStructSequence_SET_ITEM(args, pos++, Py_NewRef(exc_type)); \ |
1424 | 0 | } while (0) |
1425 | | |
1426 | |
|
1427 | 0 | ADD_ITEM(exc_type); |
1428 | 0 | ADD_ITEM(exc_value); |
1429 | 0 | ADD_ITEM(exc_tb); |
1430 | 0 | ADD_ITEM(err_msg); |
1431 | 0 | ADD_ITEM(obj); |
1432 | 0 | #undef ADD_ITEM |
1433 | |
|
1434 | 0 | if (_PyErr_Occurred(tstate)) { |
1435 | 0 | Py_DECREF(args); |
1436 | 0 | return NULL; |
1437 | 0 | } |
1438 | 0 | return args; |
1439 | 0 | } |
1440 | | |
1441 | | |
1442 | | |
1443 | | /* Default implementation of sys.unraisablehook. |
1444 | | |
1445 | | It can be called to log the exception of a custom sys.unraisablehook. |
1446 | | |
1447 | | Do nothing if sys.stderr attribute doesn't exist or is set to None. */ |
1448 | | static int |
1449 | | write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, |
1450 | | PyObject *exc_value, PyObject *exc_tb, |
1451 | | PyObject *err_msg, PyObject *obj, PyObject *file) |
1452 | 0 | { |
1453 | 0 | if (obj != NULL && obj != Py_None) { |
1454 | 0 | if (err_msg != NULL && err_msg != Py_None) { |
1455 | 0 | if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { |
1456 | 0 | return -1; |
1457 | 0 | } |
1458 | 0 | if (PyFile_WriteString(": ", file) < 0) { |
1459 | 0 | return -1; |
1460 | 0 | } |
1461 | 0 | } |
1462 | 0 | else { |
1463 | 0 | if (PyFile_WriteString("Exception ignored in: ", file) < 0) { |
1464 | 0 | return -1; |
1465 | 0 | } |
1466 | 0 | } |
1467 | | |
1468 | 0 | if (PyFile_WriteObject(obj, file, 0) < 0) { |
1469 | 0 | _PyErr_Clear(tstate); |
1470 | 0 | if (PyFile_WriteString("<object repr() failed>", file) < 0) { |
1471 | 0 | return -1; |
1472 | 0 | } |
1473 | 0 | } |
1474 | 0 | if (PyFile_WriteString("\n", file) < 0) { |
1475 | 0 | return -1; |
1476 | 0 | } |
1477 | 0 | } |
1478 | 0 | else if (err_msg != NULL && err_msg != Py_None) { |
1479 | 0 | if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { |
1480 | 0 | return -1; |
1481 | 0 | } |
1482 | 0 | if (PyFile_WriteString(":\n", file) < 0) { |
1483 | 0 | return -1; |
1484 | 0 | } |
1485 | 0 | } |
1486 | | |
1487 | 0 | if (exc_tb != NULL && exc_tb != Py_None) { |
1488 | 0 | if (PyTraceBack_Print(exc_tb, file) < 0) { |
1489 | | /* continue even if writing the traceback failed */ |
1490 | 0 | _PyErr_Clear(tstate); |
1491 | 0 | } |
1492 | 0 | } |
1493 | |
|
1494 | 0 | if (exc_type == NULL || exc_type == Py_None) { |
1495 | 0 | return -1; |
1496 | 0 | } |
1497 | | |
1498 | 0 | assert(PyExceptionClass_Check(exc_type)); |
1499 | |
|
1500 | 0 | PyObject *modulename = PyObject_GetAttr(exc_type, &_Py_ID(__module__)); |
1501 | 0 | if (modulename == NULL || !PyUnicode_Check(modulename)) { |
1502 | 0 | Py_XDECREF(modulename); |
1503 | 0 | _PyErr_Clear(tstate); |
1504 | 0 | if (PyFile_WriteString("<unknown>", file) < 0) { |
1505 | 0 | return -1; |
1506 | 0 | } |
1507 | 0 | } |
1508 | 0 | else { |
1509 | 0 | if (!_PyUnicode_Equal(modulename, &_Py_ID(builtins)) && |
1510 | 0 | !_PyUnicode_Equal(modulename, &_Py_ID(__main__))) { |
1511 | 0 | if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) { |
1512 | 0 | Py_DECREF(modulename); |
1513 | 0 | return -1; |
1514 | 0 | } |
1515 | 0 | Py_DECREF(modulename); |
1516 | 0 | if (PyFile_WriteString(".", file) < 0) { |
1517 | 0 | return -1; |
1518 | 0 | } |
1519 | 0 | } |
1520 | 0 | else { |
1521 | 0 | Py_DECREF(modulename); |
1522 | 0 | } |
1523 | 0 | } |
1524 | | |
1525 | 0 | PyObject *qualname = PyType_GetQualName((PyTypeObject *)exc_type); |
1526 | 0 | if (qualname == NULL || !PyUnicode_Check(qualname)) { |
1527 | 0 | Py_XDECREF(qualname); |
1528 | 0 | _PyErr_Clear(tstate); |
1529 | 0 | if (PyFile_WriteString("<unknown>", file) < 0) { |
1530 | 0 | return -1; |
1531 | 0 | } |
1532 | 0 | } |
1533 | 0 | else { |
1534 | 0 | if (PyFile_WriteObject(qualname, file, Py_PRINT_RAW) < 0) { |
1535 | 0 | Py_DECREF(qualname); |
1536 | 0 | return -1; |
1537 | 0 | } |
1538 | 0 | Py_DECREF(qualname); |
1539 | 0 | } |
1540 | | |
1541 | 0 | if (exc_value && exc_value != Py_None) { |
1542 | 0 | if (PyFile_WriteString(": ", file) < 0) { |
1543 | 0 | return -1; |
1544 | 0 | } |
1545 | 0 | if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) { |
1546 | 0 | _PyErr_Clear(tstate); |
1547 | 0 | if (PyFile_WriteString("<exception str() failed>", file) < 0) { |
1548 | 0 | return -1; |
1549 | 0 | } |
1550 | 0 | } |
1551 | 0 | } |
1552 | | |
1553 | 0 | if (PyFile_WriteString("\n", file) < 0) { |
1554 | 0 | return -1; |
1555 | 0 | } |
1556 | | |
1557 | | /* Explicitly call file.flush() */ |
1558 | 0 | if (_PyFile_Flush(file) < 0) { |
1559 | 0 | return -1; |
1560 | 0 | } |
1561 | | |
1562 | 0 | return 0; |
1563 | 0 | } |
1564 | | |
1565 | | |
1566 | | static int |
1567 | | write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, |
1568 | | PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, |
1569 | | PyObject *obj) |
1570 | 0 | { |
1571 | 0 | PyObject *file; |
1572 | 0 | if (PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) { |
1573 | 0 | return -1; |
1574 | 0 | } |
1575 | 0 | if (file == NULL || file == Py_None) { |
1576 | 0 | Py_XDECREF(file); |
1577 | 0 | return 0; |
1578 | 0 | } |
1579 | | |
1580 | 0 | int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, |
1581 | 0 | err_msg, obj, file); |
1582 | 0 | Py_DECREF(file); |
1583 | |
|
1584 | 0 | return res; |
1585 | 0 | } |
1586 | | |
1587 | | |
1588 | | PyObject* |
1589 | | _PyErr_WriteUnraisableDefaultHook(PyObject *args) |
1590 | 0 | { |
1591 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
1592 | |
|
1593 | 0 | if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) { |
1594 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
1595 | 0 | "sys.unraisablehook argument type " |
1596 | 0 | "must be UnraisableHookArgs"); |
1597 | 0 | return NULL; |
1598 | 0 | } |
1599 | | |
1600 | | /* Borrowed references */ |
1601 | 0 | PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); |
1602 | 0 | PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); |
1603 | 0 | PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); |
1604 | 0 | PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3); |
1605 | 0 | PyObject *obj = PyStructSequence_GET_ITEM(args, 4); |
1606 | |
|
1607 | 0 | if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) { |
1608 | 0 | return NULL; |
1609 | 0 | } |
1610 | 0 | Py_RETURN_NONE; |
1611 | 0 | } |
1612 | | |
1613 | | |
1614 | | /* Call sys.unraisablehook(). |
1615 | | |
1616 | | This function can be used when an exception has occurred but there is no way |
1617 | | for Python to handle it. For example, when a destructor raises an exception |
1618 | | or during garbage collection (gc.collect()). |
1619 | | |
1620 | | If format is non-NULL, the error message is formatted using format and |
1621 | | variable arguments as in PyUnicode_FromFormat(). |
1622 | | Otherwise, use "Exception ignored in" error message. |
1623 | | |
1624 | | An exception must be set when calling this function. */ |
1625 | | |
1626 | | static void |
1627 | | format_unraisable_v(const char *format, va_list va, PyObject *obj) |
1628 | 0 | { |
1629 | 0 | const char *err_msg_str; |
1630 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
1631 | 0 | _Py_EnsureTstateNotNULL(tstate); |
1632 | |
|
1633 | 0 | PyObject *err_msg = NULL; |
1634 | 0 | PyObject *exc_type, *exc_value, *exc_tb; |
1635 | 0 | _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); |
1636 | |
|
1637 | 0 | assert(exc_type != NULL); |
1638 | |
|
1639 | 0 | if (exc_type == NULL) { |
1640 | | /* sys.unraisablehook requires that at least exc_type is set */ |
1641 | 0 | goto default_hook; |
1642 | 0 | } |
1643 | | |
1644 | 0 | if (exc_tb == NULL) { |
1645 | 0 | PyFrameObject *frame = PyThreadState_GetFrame(tstate); |
1646 | 0 | if (frame != NULL) { |
1647 | 0 | exc_tb = _PyTraceBack_FromFrame(NULL, frame); |
1648 | 0 | if (exc_tb == NULL) { |
1649 | 0 | _PyErr_Clear(tstate); |
1650 | 0 | } |
1651 | 0 | Py_DECREF(frame); |
1652 | 0 | } |
1653 | 0 | } |
1654 | |
|
1655 | 0 | _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb); |
1656 | |
|
1657 | 0 | if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) { |
1658 | 0 | if (PyException_SetTraceback(exc_value, exc_tb) < 0) { |
1659 | 0 | _PyErr_Clear(tstate); |
1660 | 0 | } |
1661 | 0 | } |
1662 | |
|
1663 | 0 | if (format != NULL) { |
1664 | 0 | err_msg = PyUnicode_FromFormatV(format, va); |
1665 | 0 | if (err_msg == NULL) { |
1666 | 0 | PyErr_Clear(); |
1667 | 0 | } |
1668 | 0 | } |
1669 | |
|
1670 | 0 | PyObject *hook_args = make_unraisable_hook_args( |
1671 | 0 | tstate, exc_type, exc_value, exc_tb, err_msg, obj); |
1672 | 0 | if (hook_args == NULL) { |
1673 | 0 | err_msg_str = ("Exception ignored while building " |
1674 | 0 | "sys.unraisablehook arguments"); |
1675 | 0 | goto error; |
1676 | 0 | } |
1677 | | |
1678 | 0 | PyObject *hook; |
1679 | 0 | if (PySys_GetOptionalAttr(&_Py_ID(unraisablehook), &hook) < 0) { |
1680 | 0 | Py_DECREF(hook_args); |
1681 | 0 | err_msg_str = NULL; |
1682 | 0 | obj = NULL; |
1683 | 0 | goto error; |
1684 | 0 | } |
1685 | 0 | if (hook == NULL) { |
1686 | 0 | Py_DECREF(hook_args); |
1687 | 0 | goto default_hook; |
1688 | 0 | } |
1689 | | |
1690 | 0 | if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) { |
1691 | 0 | Py_DECREF(hook); |
1692 | 0 | Py_DECREF(hook_args); |
1693 | 0 | err_msg_str = "Exception ignored in audit hook"; |
1694 | 0 | obj = NULL; |
1695 | 0 | goto error; |
1696 | 0 | } |
1697 | | |
1698 | 0 | if (hook == Py_None) { |
1699 | 0 | Py_DECREF(hook); |
1700 | 0 | Py_DECREF(hook_args); |
1701 | 0 | goto default_hook; |
1702 | 0 | } |
1703 | | |
1704 | 0 | PyObject *res = PyObject_CallOneArg(hook, hook_args); |
1705 | 0 | Py_DECREF(hook); |
1706 | 0 | Py_DECREF(hook_args); |
1707 | 0 | if (res != NULL) { |
1708 | 0 | Py_DECREF(res); |
1709 | 0 | goto done; |
1710 | 0 | } |
1711 | | |
1712 | | /* sys.unraisablehook failed: log its error using default hook */ |
1713 | 0 | obj = hook; |
1714 | 0 | err_msg_str = NULL; |
1715 | |
|
1716 | 0 | error: |
1717 | | /* err_msg_str and obj have been updated and we have a new exception */ |
1718 | 0 | Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ? |
1719 | 0 | err_msg_str : "Exception ignored in sys.unraisablehook")); |
1720 | 0 | Py_XDECREF(exc_type); |
1721 | 0 | Py_XDECREF(exc_value); |
1722 | 0 | Py_XDECREF(exc_tb); |
1723 | 0 | _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); |
1724 | |
|
1725 | 0 | default_hook: |
1726 | | /* Call the default unraisable hook (ignore failure) */ |
1727 | 0 | (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, |
1728 | 0 | err_msg, obj); |
1729 | |
|
1730 | 0 | done: |
1731 | 0 | Py_XDECREF(exc_type); |
1732 | 0 | Py_XDECREF(exc_value); |
1733 | 0 | Py_XDECREF(exc_tb); |
1734 | 0 | Py_XDECREF(err_msg); |
1735 | 0 | _PyErr_Clear(tstate); /* Just in case */ |
1736 | 0 | } |
1737 | | |
1738 | | void |
1739 | | PyErr_FormatUnraisable(const char *format, ...) |
1740 | 0 | { |
1741 | 0 | va_list va; |
1742 | |
|
1743 | 0 | va_start(va, format); |
1744 | 0 | format_unraisable_v(format, va, NULL); |
1745 | 0 | va_end(va); |
1746 | 0 | } |
1747 | | |
1748 | | static void |
1749 | | format_unraisable(PyObject *obj, const char *format, ...) |
1750 | 0 | { |
1751 | 0 | va_list va; |
1752 | |
|
1753 | 0 | va_start(va, format); |
1754 | 0 | format_unraisable_v(format, va, obj); |
1755 | 0 | va_end(va); |
1756 | 0 | } |
1757 | | |
1758 | | void |
1759 | | PyErr_WriteUnraisable(PyObject *obj) |
1760 | 0 | { |
1761 | 0 | format_unraisable(obj, NULL); |
1762 | 0 | } |
1763 | | |
1764 | | |
1765 | | void |
1766 | | PyErr_SyntaxLocation(const char *filename, int lineno) |
1767 | 0 | { |
1768 | 0 | PyErr_SyntaxLocationEx(filename, lineno, -1); |
1769 | 0 | } |
1770 | | |
1771 | | |
1772 | | /* Set file and line information for the current exception. |
1773 | | If the exception is not a SyntaxError, also sets additional attributes |
1774 | | to make printing of exceptions believe it is a syntax error. */ |
1775 | | |
1776 | | static void |
1777 | | PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, |
1778 | | int end_lineno, int end_col_offset) |
1779 | 23 | { |
1780 | 23 | PyThreadState *tstate = _PyThreadState_GET(); |
1781 | | |
1782 | | /* add attributes for the line number and filename for the error */ |
1783 | 23 | PyObject *exc = _PyErr_GetRaisedException(tstate); |
1784 | | /* XXX check that it is, indeed, a syntax error. It might not |
1785 | | * be, though. */ |
1786 | 23 | PyObject *tmp = PyLong_FromLong(lineno); |
1787 | 23 | if (tmp == NULL) { |
1788 | 0 | _PyErr_Clear(tstate); |
1789 | 0 | } |
1790 | 23 | else { |
1791 | 23 | if (PyObject_SetAttr(exc, &_Py_ID(lineno), tmp)) { |
1792 | 0 | _PyErr_Clear(tstate); |
1793 | 0 | } |
1794 | 23 | Py_DECREF(tmp); |
1795 | 23 | } |
1796 | 23 | tmp = NULL; |
1797 | 23 | if (col_offset >= 0) { |
1798 | 23 | tmp = PyLong_FromLong(col_offset); |
1799 | 23 | if (tmp == NULL) { |
1800 | 0 | _PyErr_Clear(tstate); |
1801 | 0 | } |
1802 | 23 | } |
1803 | 23 | if (PyObject_SetAttr(exc, &_Py_ID(offset), tmp ? tmp : Py_None)) { |
1804 | 0 | _PyErr_Clear(tstate); |
1805 | 0 | } |
1806 | 23 | Py_XDECREF(tmp); |
1807 | | |
1808 | 23 | tmp = NULL; |
1809 | 23 | if (end_lineno >= 0) { |
1810 | 23 | tmp = PyLong_FromLong(end_lineno); |
1811 | 23 | if (tmp == NULL) { |
1812 | 0 | _PyErr_Clear(tstate); |
1813 | 0 | } |
1814 | 23 | } |
1815 | 23 | if (PyObject_SetAttr(exc, &_Py_ID(end_lineno), tmp ? tmp : Py_None)) { |
1816 | 0 | _PyErr_Clear(tstate); |
1817 | 0 | } |
1818 | 23 | Py_XDECREF(tmp); |
1819 | | |
1820 | 23 | tmp = NULL; |
1821 | 23 | if (end_col_offset >= 0) { |
1822 | 23 | tmp = PyLong_FromLong(end_col_offset); |
1823 | 23 | if (tmp == NULL) { |
1824 | 0 | _PyErr_Clear(tstate); |
1825 | 0 | } |
1826 | 23 | } |
1827 | 23 | if (PyObject_SetAttr(exc, &_Py_ID(end_offset), tmp ? tmp : Py_None)) { |
1828 | 0 | _PyErr_Clear(tstate); |
1829 | 0 | } |
1830 | 23 | Py_XDECREF(tmp); |
1831 | | |
1832 | 23 | tmp = NULL; |
1833 | 23 | if (filename != NULL) { |
1834 | 23 | if (PyObject_SetAttr(exc, &_Py_ID(filename), filename)) { |
1835 | 0 | _PyErr_Clear(tstate); |
1836 | 0 | } |
1837 | | |
1838 | 23 | tmp = PyErr_ProgramTextObject(filename, lineno); |
1839 | 23 | if (tmp) { |
1840 | 0 | if (PyObject_SetAttr(exc, &_Py_ID(text), tmp)) { |
1841 | 0 | _PyErr_Clear(tstate); |
1842 | 0 | } |
1843 | 0 | Py_DECREF(tmp); |
1844 | 0 | } |
1845 | 23 | else { |
1846 | 23 | _PyErr_Clear(tstate); |
1847 | 23 | } |
1848 | 23 | } |
1849 | 23 | if ((PyObject *)Py_TYPE(exc) != PyExc_SyntaxError) { |
1850 | 0 | int rc = PyObject_HasAttrWithError(exc, &_Py_ID(msg)); |
1851 | 0 | if (rc < 0) { |
1852 | 0 | _PyErr_Clear(tstate); |
1853 | 0 | } |
1854 | 0 | else if (!rc) { |
1855 | 0 | tmp = PyObject_Str(exc); |
1856 | 0 | if (tmp) { |
1857 | 0 | if (PyObject_SetAttr(exc, &_Py_ID(msg), tmp)) { |
1858 | 0 | _PyErr_Clear(tstate); |
1859 | 0 | } |
1860 | 0 | Py_DECREF(tmp); |
1861 | 0 | } |
1862 | 0 | else { |
1863 | 0 | _PyErr_Clear(tstate); |
1864 | 0 | } |
1865 | 0 | } |
1866 | |
|
1867 | 0 | rc = PyObject_HasAttrWithError(exc, &_Py_ID(print_file_and_line)); |
1868 | 0 | if (rc < 0) { |
1869 | 0 | _PyErr_Clear(tstate); |
1870 | 0 | } |
1871 | 0 | else if (!rc) { |
1872 | 0 | if (PyObject_SetAttr(exc, &_Py_ID(print_file_and_line), Py_None)) { |
1873 | 0 | _PyErr_Clear(tstate); |
1874 | 0 | } |
1875 | 0 | } |
1876 | 0 | } |
1877 | 23 | _PyErr_SetRaisedException(tstate, exc); |
1878 | 23 | } |
1879 | | |
1880 | | void |
1881 | 0 | PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) { |
1882 | 0 | PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, lineno, -1); |
1883 | 0 | } |
1884 | | |
1885 | | void |
1886 | | PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset, |
1887 | 23 | int end_lineno, int end_col_offset) { |
1888 | 23 | PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, end_lineno, end_col_offset); |
1889 | 23 | } |
1890 | | |
1891 | | void |
1892 | | PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) |
1893 | 0 | { |
1894 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
1895 | 0 | PyObject *fileobj; |
1896 | 0 | if (filename != NULL) { |
1897 | 0 | fileobj = PyUnicode_DecodeFSDefault(filename); |
1898 | 0 | if (fileobj == NULL) { |
1899 | 0 | _PyErr_Clear(tstate); |
1900 | 0 | } |
1901 | 0 | } |
1902 | 0 | else { |
1903 | 0 | fileobj = NULL; |
1904 | 0 | } |
1905 | 0 | PyErr_SyntaxLocationObject(fileobj, lineno, col_offset); |
1906 | 0 | Py_XDECREF(fileobj); |
1907 | 0 | } |
1908 | | |
1909 | | /* Raises a SyntaxError. |
1910 | | * If something goes wrong, a different exception may be raised. |
1911 | | */ |
1912 | | void |
1913 | | _PyErr_RaiseSyntaxError(PyObject *msg, PyObject *filename, int lineno, int col_offset, |
1914 | | int end_lineno, int end_col_offset) |
1915 | 0 | { |
1916 | 0 | PyObject *text = PyErr_ProgramTextObject(filename, lineno); |
1917 | 0 | if (text == NULL) { |
1918 | 0 | text = Py_NewRef(Py_None); |
1919 | 0 | } |
1920 | 0 | PyObject *args = Py_BuildValue("O(OiiOii)", msg, filename, |
1921 | 0 | lineno, col_offset, text, |
1922 | 0 | end_lineno, end_col_offset); |
1923 | 0 | if (args == NULL) { |
1924 | 0 | goto exit; |
1925 | 0 | } |
1926 | 0 | PyErr_SetObject(PyExc_SyntaxError, args); |
1927 | 0 | exit: |
1928 | 0 | Py_DECREF(text); |
1929 | 0 | Py_XDECREF(args); |
1930 | 0 | } |
1931 | | |
1932 | | /* Emits a SyntaxWarning and returns 0 on success. |
1933 | | If a SyntaxWarning is raised as error, replaces it with a SyntaxError |
1934 | | and returns -1. |
1935 | | */ |
1936 | | int |
1937 | | _PyErr_EmitSyntaxWarning(PyObject *msg, PyObject *filename, int lineno, int col_offset, |
1938 | | int end_lineno, int end_col_offset) |
1939 | 2.35k | { |
1940 | 2.35k | if (_PyErr_WarnExplicitObjectWithContext(PyExc_SyntaxWarning, msg, |
1941 | 2.35k | filename, lineno) < 0) |
1942 | 0 | { |
1943 | 0 | if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { |
1944 | | /* Replace the SyntaxWarning exception with a SyntaxError |
1945 | | to get a more accurate error report */ |
1946 | 0 | PyErr_Clear(); |
1947 | 0 | _PyErr_RaiseSyntaxError(msg, filename, lineno, col_offset, |
1948 | 0 | end_lineno, end_col_offset); |
1949 | 0 | } |
1950 | 0 | return -1; |
1951 | 0 | } |
1952 | 2.35k | return 0; |
1953 | 2.35k | } |
1954 | | |
1955 | | /* Attempt to load the line of text that the exception refers to. If it |
1956 | | fails, it will return NULL but will not set an exception. |
1957 | | |
1958 | | XXX The functionality of this function is quite similar to the |
1959 | | functionality in tb_displayline() in traceback.c. */ |
1960 | | |
1961 | | static PyObject * |
1962 | | err_programtext(FILE *fp, int lineno, const char* encoding) |
1963 | 0 | { |
1964 | 0 | char linebuf[1000]; |
1965 | 0 | size_t line_size = 0; |
1966 | |
|
1967 | 0 | for (int i = 0; i < lineno; ) { |
1968 | 0 | line_size = 0; |
1969 | 0 | if (_Py_UniversalNewlineFgetsWithSize(linebuf, sizeof(linebuf), |
1970 | 0 | fp, NULL, &line_size) == NULL) |
1971 | 0 | { |
1972 | | /* Error or EOF. */ |
1973 | 0 | return NULL; |
1974 | 0 | } |
1975 | | /* fgets read *something*; if it didn't fill the |
1976 | | whole buffer, it must have found a newline |
1977 | | or hit the end of the file; if the last character is \n, |
1978 | | it obviously found a newline; else we haven't |
1979 | | yet seen a newline, so must continue */ |
1980 | 0 | if (i + 1 < lineno |
1981 | 0 | && line_size == sizeof(linebuf) - 1 |
1982 | 0 | && linebuf[sizeof(linebuf) - 2] != '\n') |
1983 | 0 | { |
1984 | 0 | continue; |
1985 | 0 | } |
1986 | 0 | i++; |
1987 | 0 | } |
1988 | | |
1989 | 0 | const char *line = linebuf; |
1990 | | /* Skip BOM. */ |
1991 | 0 | if (lineno == 1 && line_size >= 3 && memcmp(line, "\xef\xbb\xbf", 3) == 0) { |
1992 | 0 | line += 3; |
1993 | 0 | line_size -= 3; |
1994 | 0 | } |
1995 | 0 | PyObject *res = PyUnicode_Decode(line, line_size, encoding, "replace"); |
1996 | 0 | if (res == NULL) { |
1997 | 0 | PyErr_Clear(); |
1998 | 0 | } |
1999 | 0 | return res; |
2000 | 0 | } |
2001 | | |
2002 | | PyObject * |
2003 | | PyErr_ProgramText(const char *filename, int lineno) |
2004 | 0 | { |
2005 | 0 | if (filename == NULL) { |
2006 | 0 | return NULL; |
2007 | 0 | } |
2008 | | |
2009 | 0 | PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); |
2010 | 0 | if (filename_obj == NULL) { |
2011 | 0 | PyErr_Clear(); |
2012 | 0 | return NULL; |
2013 | 0 | } |
2014 | 0 | PyObject *res = PyErr_ProgramTextObject(filename_obj, lineno); |
2015 | 0 | Py_DECREF(filename_obj); |
2016 | 0 | return res; |
2017 | 0 | } |
2018 | | |
2019 | | /* Function from Parser/tokenizer/file_tokenizer.c */ |
2020 | | extern char* _PyTokenizer_FindEncodingFilename(int, PyObject *); |
2021 | | |
2022 | | PyObject * |
2023 | | _PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* encoding) |
2024 | 11.8k | { |
2025 | 11.8k | char *found_encoding = NULL; |
2026 | 11.8k | if (filename == NULL || lineno <= 0) { |
2027 | 0 | return NULL; |
2028 | 0 | } |
2029 | | |
2030 | 11.8k | FILE *fp = Py_fopen(filename, "r" PY_STDIOTEXTMODE); |
2031 | 11.8k | if (fp == NULL) { |
2032 | 11.8k | PyErr_Clear(); |
2033 | 11.8k | return NULL; |
2034 | 11.8k | } |
2035 | 0 | if (encoding == NULL) { |
2036 | 0 | int fd = fileno(fp); |
2037 | 0 | found_encoding = _PyTokenizer_FindEncodingFilename(fd, filename); |
2038 | 0 | encoding = found_encoding; |
2039 | 0 | if (encoding == NULL) { |
2040 | 0 | PyErr_Clear(); |
2041 | 0 | encoding = "utf-8"; |
2042 | 0 | } |
2043 | | /* Reset position */ |
2044 | 0 | if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { |
2045 | 0 | fclose(fp); |
2046 | 0 | PyMem_Free(found_encoding); |
2047 | 0 | return NULL; |
2048 | 0 | } |
2049 | 0 | } |
2050 | 0 | PyObject *res = err_programtext(fp, lineno, encoding); |
2051 | 0 | fclose(fp); |
2052 | 0 | PyMem_Free(found_encoding); |
2053 | 0 | return res; |
2054 | 0 | } |
2055 | | |
2056 | | PyObject * |
2057 | | PyErr_ProgramTextObject(PyObject *filename, int lineno) |
2058 | 23 | { |
2059 | 23 | return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL); |
2060 | 23 | } |