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