LCOV - code coverage report
Current view: top level - Python - errors.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 646 778 83.0 %
Date: 2022-07-07 18:19:46 Functions: 65 70 92.9 %

          Line data    Source code
       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    60601700 : _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
      33             :                PyObject *traceback)
      34             : {
      35             :     PyObject *oldtype, *oldvalue, *oldtraceback;
      36             : 
      37    60601700 :     if (traceback != NULL && !PyTraceBack_Check(traceback)) {
      38             :         /* XXX Should never happen -- fatal error instead? */
      39             :         /* Well, it could be None. */
      40         195 :         Py_DECREF(traceback);
      41         195 :         traceback = NULL;
      42             :     }
      43             : 
      44             :     /* Save these in locals to safeguard against recursive
      45             :        invocation through Py_XDECREF */
      46    60601700 :     oldtype = tstate->curexc_type;
      47    60601700 :     oldvalue = tstate->curexc_value;
      48    60601700 :     oldtraceback = tstate->curexc_traceback;
      49             : 
      50    60601700 :     tstate->curexc_type = type;
      51    60601700 :     tstate->curexc_value = value;
      52    60601700 :     tstate->curexc_traceback = traceback;
      53             : 
      54    60601700 :     Py_XDECREF(oldtype);
      55    60601700 :     Py_XDECREF(oldvalue);
      56    60601700 :     Py_XDECREF(oldtraceback);
      57    60601700 : }
      58             : 
      59             : void
      60    22135900 : PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
      61             : {
      62    22135900 :     PyThreadState *tstate = _PyThreadState_GET();
      63    22135900 :     _PyErr_Restore(tstate, type, value, traceback);
      64    22135900 : }
      65             : 
      66             : 
      67             : _PyErr_StackItem *
      68    12836600 : _PyErr_GetTopmostException(PyThreadState *tstate)
      69             : {
      70    12836600 :     _PyErr_StackItem *exc_info = tstate->exc_info;
      71    12836600 :     assert(exc_info);
      72             : 
      73    18361700 :     while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) &&
      74    17819700 :            exc_info->previous_item != NULL)
      75             :     {
      76     5525100 :         exc_info = exc_info->previous_item;
      77             :     }
      78    12836600 :     return exc_info;
      79             : }
      80             : 
      81             : static PyObject*
      82     4395650 : _PyErr_CreateException(PyObject *exception_type, PyObject *value)
      83             : {
      84             :     PyObject *exc;
      85             : 
      86     4395650 :     if (value == NULL || value == Py_None) {
      87     1239930 :         exc = _PyObject_CallNoArgs(exception_type);
      88             :     }
      89     3155720 :     else if (PyTuple_Check(value)) {
      90      889225 :         exc = PyObject_Call(exception_type, value, NULL);
      91             :     }
      92             :     else {
      93     2266490 :         exc = PyObject_CallOneArg(exception_type, value);
      94             :     }
      95             : 
      96     4395650 :     if (exc != NULL && !PyExceptionInstance_Check(exc)) {
      97           2 :         PyErr_Format(PyExc_TypeError,
      98             :                      "calling %R should have returned an instance of "
      99             :                      "BaseException, not %s",
     100           2 :                      exception_type, Py_TYPE(exc)->tp_name);
     101           2 :         Py_CLEAR(exc);
     102             :     }
     103             : 
     104     4395650 :     return exc;
     105             : }
     106             : 
     107             : void
     108    12811300 : _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
     109             : {
     110             :     PyObject *exc_value;
     111    12811300 :     PyObject *tb = NULL;
     112             : 
     113    25622600 :     if (exception != NULL &&
     114    25622600 :         !PyExceptionClass_Check(exception)) {
     115           1 :         _PyErr_Format(tstate, PyExc_SystemError,
     116             :                       "_PyErr_SetObject: "
     117             :                       "exception %R is not a BaseException subclass",
     118             :                       exception);
     119           1 :         return;
     120             :     }
     121             : 
     122    12811300 :     Py_XINCREF(value);
     123    12811300 :     exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
     124    12811300 :     if (exc_value != NULL && exc_value != Py_None) {
     125             :         /* Implicit exception chaining */
     126      526076 :         Py_INCREF(exc_value);
     127      526076 :         if (value == NULL || !PyExceptionInstance_Check(value)) {
     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      304299 :             _PyErr_Clear(tstate);
     134             : 
     135      304299 :             fixed_value = _PyErr_CreateException(exception, value);
     136      304299 :             Py_XDECREF(value);
     137      304299 :             if (fixed_value == NULL) {
     138           2 :                 Py_DECREF(exc_value);
     139           2 :                 return;
     140             :             }
     141             : 
     142      304297 :             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      526074 :         if (exc_value != value) {
     152      524575 :             PyObject *o = exc_value, *context;
     153      524575 :             PyObject *slow_o = o;  /* Floyd's cycle detection algo */
     154      524575 :             int slow_update_toggle = 0;
     155    34628200 :             while ((context = PyException_GetContext(o))) {
     156    34103600 :                 Py_DECREF(context);
     157    34103600 :                 if (context == value) {
     158           4 :                     PyException_SetContext(o, NULL);
     159           4 :                     break;
     160             :                 }
     161    34103600 :                 o = context;
     162    34103600 :                 if (o == slow_o) {
     163             :                     /* pre-existing cycle - all exceptions on the
     164             :                        path were visited and checked.  */
     165           4 :                     break;
     166             :                 }
     167    34103600 :                 if (slow_update_toggle) {
     168    17011500 :                     slow_o = PyException_GetContext(slow_o);
     169    17011500 :                     Py_DECREF(slow_o);
     170             :                 }
     171    34103600 :                 slow_update_toggle = !slow_update_toggle;
     172             :             }
     173      524575 :             PyException_SetContext(value, exc_value);
     174             :         }
     175             :         else {
     176        1499 :             Py_DECREF(exc_value);
     177             :         }
     178             :     }
     179    12811300 :     if (value != NULL && PyExceptionInstance_Check(value))
     180     2048790 :         tb = PyException_GetTraceback(value);
     181    12811300 :     Py_XINCREF(exception);
     182    12811300 :     _PyErr_Restore(tstate, exception, value, tb);
     183             : }
     184             : 
     185             : void
     186      471582 : PyErr_SetObject(PyObject *exception, PyObject *value)
     187             : {
     188      471582 :     PyThreadState *tstate = _PyThreadState_GET();
     189      471582 :     _PyErr_SetObject(tstate, exception, value);
     190      471582 : }
     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     1192520 : _PyErr_SetKeyError(PyObject *arg)
     197             : {
     198     1192520 :     PyThreadState *tstate = _PyThreadState_GET();
     199     1192520 :     PyObject *tup = PyTuple_Pack(1, arg);
     200     1192520 :     if (!tup) {
     201             :         /* caller will expect error to be set anyway */
     202           0 :         return;
     203             :     }
     204     1192520 :     _PyErr_SetObject(tstate, PyExc_KeyError, tup);
     205     1192520 :     Py_DECREF(tup);
     206             : }
     207             : 
     208             : void
     209     1774360 : _PyErr_SetNone(PyThreadState *tstate, PyObject *exception)
     210             : {
     211     1774360 :     _PyErr_SetObject(tstate, exception, (PyObject *)NULL);
     212     1774360 : }
     213             : 
     214             : 
     215             : void
     216     1773010 : PyErr_SetNone(PyObject *exception)
     217             : {
     218     1773010 :     PyThreadState *tstate = _PyThreadState_GET();
     219     1773010 :     _PyErr_SetNone(tstate, exception);
     220     1773010 : }
     221             : 
     222             : 
     223             : void
     224      596669 : _PyErr_SetString(PyThreadState *tstate, PyObject *exception,
     225             :                  const char *string)
     226             : {
     227      596669 :     PyObject *value = PyUnicode_FromString(string);
     228      596669 :     _PyErr_SetObject(tstate, exception, value);
     229      596669 :     Py_XDECREF(value);
     230      596669 : }
     231             : 
     232             : void
     233      596390 : PyErr_SetString(PyObject *exception, const char *string)
     234             : {
     235      596390 :     PyThreadState *tstate = _PyThreadState_GET();
     236      596390 :     _PyErr_SetString(tstate, exception, string);
     237      596390 : }
     238             : 
     239             : 
     240             : PyObject* _Py_HOT_FUNCTION
     241   843795000 : PyErr_Occurred(void)
     242             : {
     243             :     /* The caller must hold the GIL. */
     244   843795000 :     assert(PyGILState_Check());
     245             : 
     246   843795000 :     PyThreadState *tstate = _PyThreadState_GET();
     247   843795000 :     return _PyErr_Occurred(tstate);
     248             : }
     249             : 
     250             : 
     251             : int
     252    15133000 : PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
     253             : {
     254    15133000 :     if (err == NULL || exc == NULL) {
     255             :         /* maybe caused by "import exceptions" that failed early on */
     256      150405 :         return 0;
     257             :     }
     258    14982600 :     if (PyTuple_Check(exc)) {
     259             :         Py_ssize_t i, n;
     260      178023 :         n = PyTuple_Size(exc);
     261      209656 :         for (i = 0; i < n; i++) {
     262             :             /* Test recursively */
     263      208903 :              if (PyErr_GivenExceptionMatches(
     264      208903 :                  err, PyTuple_GET_ITEM(exc, i)))
     265             :              {
     266      177270 :                  return 1;
     267             :              }
     268             :         }
     269         753 :         return 0;
     270             :     }
     271             :     /* err might be an instance, so check its class. */
     272    14804600 :     if (PyExceptionInstance_Check(err))
     273     6154330 :         err = PyExceptionInstance_Class(err);
     274             : 
     275    14804600 :     if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
     276    14804600 :         return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc);
     277             :     }
     278             : 
     279           0 :     return err == exc;
     280             : }
     281             : 
     282             : 
     283             : int
     284     8797280 : _PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc)
     285             : {
     286     8797280 :     return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
     287             : }
     288             : 
     289             : 
     290             : int
     291     8699050 : PyErr_ExceptionMatches(PyObject *exc)
     292             : {
     293     8699050 :     PyThreadState *tstate = _PyThreadState_GET();
     294     8699050 :     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     6870130 : _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
     310             :                           PyObject **val, PyObject **tb)
     311             : {
     312     6870130 :     int recursion_depth = 0;
     313     6870130 :     tstate->recursion_headroom++;
     314             :     PyObject *type, *value, *initial_tb;
     315             : 
     316     6870170 :   restart:
     317     6870170 :     type = *exc;
     318     6870170 :     if (type == NULL) {
     319             :         /* There was no exception, so nothing to do. */
     320           0 :         tstate->recursion_headroom--;
     321           0 :         return;
     322             :     }
     323             : 
     324     6870170 :     value = *val;
     325             :     /* If PyErr_SetNone() was used, the value will have been actually
     326             :        set to NULL.
     327             :     */
     328     6870170 :     if (!value) {
     329     1234010 :         value = Py_None;
     330     1234010 :         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     6870170 :     if (PyExceptionClass_Check(type)) {
     337     6870170 :         PyObject *inclass = NULL;
     338     6870170 :         int is_subclass = 0;
     339             : 
     340     6870170 :         if (PyExceptionInstance_Check(value)) {
     341     2778820 :             inclass = PyExceptionInstance_Class(value);
     342     2778820 :             is_subclass = PyObject_IsSubclass(inclass, type);
     343     2778820 :             if (is_subclass < 0) {
     344           0 :                 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     6870170 :         if (!is_subclass) {
     354     4091350 :             PyObject *fixed_value = _PyErr_CreateException(type, value);
     355     4091350 :             if (fixed_value == NULL) {
     356          37 :                 goto error;
     357             :             }
     358     4091310 :             Py_DECREF(value);
     359     4091310 :             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     2778820 :         else if (inclass != type) {
     365           0 :             Py_INCREF(inclass);
     366           0 :             Py_DECREF(type);
     367           0 :             type = inclass;
     368             :         }
     369             :     }
     370     6870130 :     *exc = type;
     371     6870130 :     *val = value;
     372     6870130 :     tstate->recursion_headroom--;
     373     6870130 :     return;
     374             : 
     375          37 :   error:
     376          37 :     Py_DECREF(type);
     377          37 :     Py_DECREF(value);
     378          37 :     recursion_depth++;
     379          37 :     if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) {
     380           1 :         _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          37 :     initial_tb = *tb;
     389          37 :     _PyErr_Fetch(tstate, exc, val, tb);
     390          37 :     assert(*exc != NULL);
     391          37 :     if (initial_tb != NULL) {
     392          34 :         if (*tb == NULL)
     393          33 :             *tb = initial_tb;
     394             :         else
     395           1 :             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          37 :     if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) {
     402           0 :         if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) {
     403           0 :             Py_FatalError("Cannot recover from MemoryErrors "
     404             :                           "while normalizing exceptions.");
     405             :         }
     406             :         else {
     407           0 :             Py_FatalError("Cannot recover from the recursive normalization "
     408             :                           "of an exception.");
     409             :         }
     410             :     }
     411          37 :     goto restart;
     412             : }
     413             : 
     414             : 
     415             : void
     416     1517690 : PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
     417             : {
     418     1517690 :     PyThreadState *tstate = _PyThreadState_GET();
     419     1517690 :     _PyErr_NormalizeException(tstate, exc, val, tb);
     420     1517690 : }
     421             : 
     422             : 
     423             : void
     424    37208800 : _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
     425             :              PyObject **p_traceback)
     426             : {
     427    37208800 :     *p_type = tstate->curexc_type;
     428    37208800 :     *p_value = tstate->curexc_value;
     429    37208800 :     *p_traceback = tstate->curexc_traceback;
     430             : 
     431    37208800 :     tstate->curexc_type = NULL;
     432    37208800 :     tstate->curexc_value = NULL;
     433    37208800 :     tstate->curexc_traceback = NULL;
     434    37208800 : }
     435             : 
     436             : 
     437             : void
     438    22493800 : PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
     439             : {
     440    22493800 :     PyThreadState *tstate = _PyThreadState_GET();
     441    22493800 :     _PyErr_Fetch(tstate, p_type, p_value, p_traceback);
     442    22493800 : }
     443             : 
     444             : 
     445             : void
     446    15601900 : _PyErr_Clear(PyThreadState *tstate)
     447             : {
     448    15601900 :     _PyErr_Restore(tstate, NULL, NULL, NULL);
     449    15601900 : }
     450             : 
     451             : 
     452             : void
     453     8144310 : PyErr_Clear(void)
     454             : {
     455     8144310 :     PyThreadState *tstate = _PyThreadState_GET();
     456     8144310 :     _PyErr_Clear(tstate);
     457     8144310 : }
     458             : 
     459             : static PyObject*
     460       11311 : get_exc_type(PyObject *exc_value)  /* returns a borrowed ref */
     461             : {
     462       11311 :     if (exc_value == NULL || exc_value == Py_None) {
     463        9403 :         return Py_None;
     464             :     }
     465             :     else {
     466        1908 :         assert(PyExceptionInstance_Check(exc_value));
     467        1908 :         PyObject *type = PyExceptionInstance_Class(exc_value);
     468        1908 :         assert(type != NULL);
     469        1908 :         return type;
     470             :     }
     471             : }
     472             : 
     473             : static PyObject*
     474       11311 : get_exc_traceback(PyObject *exc_value)  /* returns a borrowed ref */
     475             : {
     476       11311 :     if (exc_value == NULL || exc_value == Py_None) {
     477        9403 :         return Py_None;
     478             :     }
     479             :     else {
     480        1908 :         assert(PyExceptionInstance_Check(exc_value));
     481        1908 :         PyObject *tb = PyException_GetTraceback(exc_value);
     482        1908 :         Py_XDECREF(tb);
     483        1908 :         return tb ? tb : Py_None;
     484             :     }
     485             : }
     486             : 
     487             : void
     488           2 : _PyErr_GetExcInfo(PyThreadState *tstate,
     489             :                   PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
     490             : {
     491           2 :     _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
     492             : 
     493           2 :     *p_type = get_exc_type(exc_info->exc_value);
     494           2 :     *p_value = exc_info->exc_value;
     495           2 :     *p_traceback = get_exc_traceback(exc_info->exc_value);
     496             : 
     497           2 :     Py_XINCREF(*p_type);
     498           2 :     Py_XINCREF(*p_value);
     499           2 :     Py_XINCREF(*p_traceback);
     500           2 : }
     501             : 
     502             : PyObject*
     503           2 : _PyErr_GetHandledException(PyThreadState *tstate)
     504             : {
     505           2 :     _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
     506           2 :     PyObject *exc = exc_info->exc_value;
     507           2 :     if (exc == NULL || exc == Py_None) {
     508           0 :         return NULL;
     509             :     }
     510           2 :     return Py_NewRef(exc);
     511             : }
     512             : 
     513             : PyObject*
     514           2 : PyErr_GetHandledException(void)
     515             : {
     516           2 :     PyThreadState *tstate = _PyThreadState_GET();
     517           2 :     return _PyErr_GetHandledException(tstate);
     518             : }
     519             : 
     520             : void
     521         152 : _PyErr_SetHandledException(PyThreadState *tstate, PyObject *exc)
     522             : {
     523         152 :     Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc));
     524         152 : }
     525             : 
     526             : void
     527         152 : PyErr_SetHandledException(PyObject *exc)
     528             : {
     529         152 :     PyThreadState *tstate = _PyThreadState_GET();
     530         152 :     _PyErr_SetHandledException(tstate, exc);
     531         152 : }
     532             : 
     533             : void
     534           2 : PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
     535             : {
     536           2 :     PyThreadState *tstate = _PyThreadState_GET();
     537           2 :     _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback);
     538           2 : }
     539             : 
     540             : void
     541         150 : PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)
     542             : {
     543         150 :     PyErr_SetHandledException(value);
     544         150 :     Py_XDECREF(value);
     545             :     /* These args are no longer used, but we still need to steal a ref */
     546         150 :     Py_XDECREF(type);
     547         150 :     Py_XDECREF(traceback);
     548         150 : }
     549             : 
     550             : 
     551             : PyObject*
     552       11309 : _PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
     553             : {
     554       11309 :     PyObject *exc_value = err_info->exc_value;
     555             : 
     556       11309 :     assert(exc_value == NULL ||
     557             :            exc_value == Py_None ||
     558             :            PyExceptionInstance_Check(exc_value));
     559             : 
     560       11309 :     PyObject *exc_type = get_exc_type(exc_value);
     561       11309 :     PyObject *exc_traceback = get_exc_traceback(exc_value);
     562             : 
     563       11309 :     return Py_BuildValue(
     564             :         "(OOO)",
     565             :         exc_type ? exc_type : Py_None,
     566             :         exc_value ? exc_value : Py_None,
     567             :         exc_traceback ? exc_traceback : Py_None);
     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      358931 : _PyErr_ChainExceptions(PyObject *typ, PyObject *val, PyObject *tb)
     578             : {
     579      358931 :     if (typ == NULL)
     580      358861 :         return;
     581             : 
     582          70 :     PyThreadState *tstate = _PyThreadState_GET();
     583             : 
     584          70 :     if (!PyExceptionClass_Check(typ)) {
     585           0 :         _PyErr_Format(tstate, PyExc_SystemError,
     586             :                       "_PyErr_ChainExceptions: "
     587             :                       "exception %R is not a BaseException subclass",
     588             :                       typ);
     589           0 :         return;
     590             :     }
     591             : 
     592          70 :     if (_PyErr_Occurred(tstate)) {
     593             :         PyObject *typ2, *val2, *tb2;
     594          14 :         _PyErr_Fetch(tstate, &typ2, &val2, &tb2);
     595          14 :         _PyErr_NormalizeException(tstate, &typ, &val, &tb);
     596          14 :         if (tb != NULL) {
     597          10 :             PyException_SetTraceback(val, tb);
     598          10 :             Py_DECREF(tb);
     599             :         }
     600          14 :         Py_DECREF(typ);
     601          14 :         _PyErr_NormalizeException(tstate, &typ2, &val2, &tb2);
     602          14 :         PyException_SetContext(val2, val);
     603          14 :         _PyErr_Restore(tstate, typ2, val2, tb2);
     604             :     }
     605             :     else {
     606          56 :         _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      609408 : _PyErr_ChainStackItem(_PyErr_StackItem *exc_info)
     620             : {
     621      609408 :     PyThreadState *tstate = _PyThreadState_GET();
     622      609408 :     assert(_PyErr_Occurred(tstate));
     623             : 
     624             :     int exc_info_given;
     625      609408 :     if (exc_info == NULL) {
     626      609408 :         exc_info_given = 0;
     627      609408 :         exc_info = tstate->exc_info;
     628             :     } else {
     629           0 :         exc_info_given = 1;
     630             :     }
     631             : 
     632      609408 :     if (exc_info->exc_value == NULL || exc_info->exc_value == Py_None) {
     633      609355 :         return;
     634             :     }
     635             : 
     636             :     _PyErr_StackItem *saved_exc_info;
     637          53 :     if (exc_info_given) {
     638             :         /* Temporarily set the thread state's exc_info since this is what
     639             :            _PyErr_SetObject uses for implicit exception chaining. */
     640           0 :         saved_exc_info = tstate->exc_info;
     641           0 :         tstate->exc_info = exc_info;
     642             :     }
     643             : 
     644             :     PyObject *typ, *val, *tb;
     645          53 :     _PyErr_Fetch(tstate, &typ, &val, &tb);
     646             : 
     647             :     /* _PyErr_SetObject sets the context from PyThreadState. */
     648          53 :     _PyErr_SetObject(tstate, typ, val);
     649          53 :     Py_DECREF(typ);  // since _PyErr_Occurred was true
     650          53 :     Py_XDECREF(val);
     651          53 :     Py_XDECREF(tb);
     652             : 
     653          53 :     if (exc_info_given) {
     654           0 :         tstate->exc_info = saved_exc_info;
     655             :     }
     656             : }
     657             : 
     658             : static PyObject *
     659          40 : _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception,
     660             :                         const char *format, va_list vargs)
     661             : {
     662             :     PyObject *exc, *val, *val2, *tb;
     663             : 
     664          40 :     assert(_PyErr_Occurred(tstate));
     665          40 :     _PyErr_Fetch(tstate, &exc, &val, &tb);
     666          40 :     _PyErr_NormalizeException(tstate, &exc, &val, &tb);
     667          40 :     if (tb != NULL) {
     668          37 :         PyException_SetTraceback(val, tb);
     669          37 :         Py_DECREF(tb);
     670             :     }
     671          40 :     Py_DECREF(exc);
     672          40 :     assert(!_PyErr_Occurred(tstate));
     673             : 
     674          40 :     _PyErr_FormatV(tstate, exception, format, vargs);
     675             : 
     676          40 :     _PyErr_Fetch(tstate, &exc, &val2, &tb);
     677          40 :     _PyErr_NormalizeException(tstate, &exc, &val2, &tb);
     678          40 :     Py_INCREF(val);
     679          40 :     PyException_SetCause(val2, val);
     680          40 :     PyException_SetContext(val2, val);
     681          40 :     _PyErr_Restore(tstate, exc, val2, tb);
     682             : 
     683          40 :     return NULL;
     684             : }
     685             : 
     686             : PyObject *
     687           0 : _PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception,
     688             :                              const char *format, ...)
     689             : {
     690             :     va_list vargs;
     691           0 :     va_start(vargs, format);
     692           0 :     _PyErr_FormatVFromCause(tstate, exception, format, vargs);
     693           0 :     va_end(vargs);
     694           0 :     return NULL;
     695             : }
     696             : 
     697             : PyObject *
     698          40 : _PyErr_FormatFromCause(PyObject *exception, const char *format, ...)
     699             : {
     700          40 :     PyThreadState *tstate = _PyThreadState_GET();
     701             :     va_list vargs;
     702          40 :     va_start(vargs, format);
     703          40 :     _PyErr_FormatVFromCause(tstate, exception, format, vargs);
     704          40 :     va_end(vargs);
     705          40 :     return NULL;
     706             : }
     707             : 
     708             : /* Convenience functions to set a type error exception and return 0 */
     709             : 
     710             : int
     711          53 : PyErr_BadArgument(void)
     712             : {
     713          53 :     PyThreadState *tstate = _PyThreadState_GET();
     714          53 :     _PyErr_SetString(tstate, PyExc_TypeError,
     715             :                      "bad argument type for built-in operation");
     716          53 :     return 0;
     717             : }
     718             : 
     719             : PyObject *
     720        1356 : _PyErr_NoMemory(PyThreadState *tstate)
     721             : {
     722        1356 :     if (Py_IS_TYPE(PyExc_MemoryError, NULL)) {
     723             :         /* PyErr_NoMemory() has been called before PyExc_MemoryError has been
     724             :            initialized by _PyExc_Init() */
     725           0 :         Py_FatalError("Out of memory and PyExc_MemoryError is not "
     726             :                       "initialized yet");
     727             :     }
     728        1356 :     _PyErr_SetNone(tstate, PyExc_MemoryError);
     729        1356 :     return NULL;
     730             : }
     731             : 
     732             : PyObject *
     733        1224 : PyErr_NoMemory(void)
     734             : {
     735        1224 :     PyThreadState *tstate = _PyThreadState_GET();
     736        1224 :     return _PyErr_NoMemory(tstate);
     737             : }
     738             : 
     739             : PyObject *
     740      264029 : PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
     741             : {
     742      264029 :     return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL);
     743             : }
     744             : 
     745             : PyObject *
     746     1359180 : PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2)
     747             : {
     748     1359180 :     PyThreadState *tstate = _PyThreadState_GET();
     749             :     PyObject *message;
     750             :     PyObject *v, *args;
     751     1359180 :     int i = errno;
     752             : #ifdef MS_WINDOWS
     753             :     WCHAR *s_buf = NULL;
     754             : #endif /* Unix/Windows */
     755             : 
     756             : #ifdef EINTR
     757     1359180 :     if (i == EINTR && PyErr_CheckSignals())
     758           0 :         return NULL;
     759             : #endif
     760             : 
     761             : #ifndef MS_WINDOWS
     762     1359180 :     if (i != 0) {
     763     1359180 :         const char *s = strerror(i);
     764     1359180 :         message = PyUnicode_DecodeLocale(s, "surrogateescape");
     765             :     }
     766             :     else {
     767             :         /* Sometimes errno didn't get set */
     768           0 :         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     1359180 :     if (message == NULL)
     812             :     {
     813             : #ifdef MS_WINDOWS
     814             :         LocalFree(s_buf);
     815             : #endif
     816           0 :         return NULL;
     817             :     }
     818             : 
     819     1359180 :     if (filenameObject != NULL) {
     820      264163 :         if (filenameObject2 != NULL)
     821         127 :             args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2);
     822             :         else
     823      264036 :             args = Py_BuildValue("(iOO)", i, message, filenameObject);
     824             :     } else {
     825     1095020 :         assert(filenameObject2 == NULL);
     826     1095020 :         args = Py_BuildValue("(iO)", i, message);
     827             :     }
     828     1359180 :     Py_DECREF(message);
     829             : 
     830     1359180 :     if (args != NULL) {
     831     1359180 :         v = PyObject_Call(exc, args, NULL);
     832     1359180 :         Py_DECREF(args);
     833     1359180 :         if (v != NULL) {
     834     1359180 :             _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
     835     1359180 :             Py_DECREF(v);
     836             :         }
     837             :     }
     838             : #ifdef MS_WINDOWS
     839             :     LocalFree(s_buf);
     840             : #endif
     841     1359180 :     return NULL;
     842             : }
     843             : 
     844             : PyObject *
     845           7 : PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
     846             : {
     847           7 :     PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
     848           7 :     PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
     849           7 :     Py_XDECREF(name);
     850           7 :     return result;
     851             : }
     852             : 
     853             : PyObject *
     854     1095020 : PyErr_SetFromErrno(PyObject *exc)
     855             : {
     856     1095020 :     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        4822 : PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
     980             :     PyObject *name, PyObject *path)
     981             : {
     982        4822 :     PyThreadState *tstate = _PyThreadState_GET();
     983             :     int issubclass;
     984             :     PyObject *kwargs, *error;
     985             : 
     986        4822 :     issubclass = PyObject_IsSubclass(exception, PyExc_ImportError);
     987        4822 :     if (issubclass < 0) {
     988           0 :         return NULL;
     989             :     }
     990        4822 :     else if (!issubclass) {
     991           0 :         _PyErr_SetString(tstate, PyExc_TypeError,
     992             :                          "expected a subclass of ImportError");
     993           0 :         return NULL;
     994             :     }
     995             : 
     996        4822 :     if (msg == NULL) {
     997           0 :         _PyErr_SetString(tstate, PyExc_TypeError,
     998             :                          "expected a message argument");
     999           0 :         return NULL;
    1000             :     }
    1001             : 
    1002        4822 :     if (name == NULL) {
    1003           2 :         name = Py_None;
    1004             :     }
    1005        4822 :     if (path == NULL) {
    1006        3132 :         path = Py_None;
    1007             :     }
    1008             : 
    1009        4822 :     kwargs = PyDict_New();
    1010        4822 :     if (kwargs == NULL) {
    1011           0 :         return NULL;
    1012             :     }
    1013        4822 :     if (PyDict_SetItemString(kwargs, "name", name) < 0) {
    1014           0 :         goto done;
    1015             :     }
    1016        4822 :     if (PyDict_SetItemString(kwargs, "path", path) < 0) {
    1017           0 :         goto done;
    1018             :     }
    1019             : 
    1020        4822 :     error = PyObject_VectorcallDict(exception, &msg, 1, kwargs);
    1021        4822 :     if (error != NULL) {
    1022        4822 :         _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error);
    1023        4822 :         Py_DECREF(error);
    1024             :     }
    1025             : 
    1026           0 : done:
    1027        4822 :     Py_DECREF(kwargs);
    1028        4822 :     return NULL;
    1029             : }
    1030             : 
    1031             : PyObject *
    1032        4822 : PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
    1033             : {
    1034        4822 :     return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path);
    1035             : }
    1036             : 
    1037             : void
    1038          21 : _PyErr_BadInternalCall(const char *filename, int lineno)
    1039             : {
    1040          21 :     PyThreadState *tstate = _PyThreadState_GET();
    1041          21 :     _PyErr_Format(tstate, PyExc_SystemError,
    1042             :                   "%s:%d: bad argument to internal function",
    1043             :                   filename, lineno);
    1044          21 : }
    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           0 : PyErr_BadInternalCall(void)
    1051             : {
    1052           0 :     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     7043130 : _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     7043130 :     _PyErr_Clear(tstate);
    1069             : 
    1070     7043130 :     string = PyUnicode_FromFormatV(format, vargs);
    1071             : 
    1072     7043130 :     _PyErr_SetObject(tstate, exception, string);
    1073     7043130 :     Py_XDECREF(string);
    1074     7043130 :     return NULL;
    1075             : }
    1076             : 
    1077             : 
    1078             : PyObject *
    1079           4 : PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
    1080             : {
    1081           4 :     PyThreadState *tstate = _PyThreadState_GET();
    1082           4 :     return _PyErr_FormatV(tstate, exception, format, vargs);
    1083             : }
    1084             : 
    1085             : 
    1086             : PyObject *
    1087       15155 : _PyErr_Format(PyThreadState *tstate, PyObject *exception,
    1088             :               const char *format, ...)
    1089             : {
    1090             :     va_list vargs;
    1091       15155 :     va_start(vargs, format);
    1092       15155 :     _PyErr_FormatV(tstate, exception, format, vargs);
    1093       15155 :     va_end(vargs);
    1094       15155 :     return NULL;
    1095             : }
    1096             : 
    1097             : 
    1098             : PyObject *
    1099     7027930 : PyErr_Format(PyObject *exception, const char *format, ...)
    1100             : {
    1101     7027930 :     PyThreadState *tstate = _PyThreadState_GET();
    1102             :     va_list vargs;
    1103     7027930 :     va_start(vargs, format);
    1104     7027930 :     _PyErr_FormatV(tstate, exception, format, vargs);
    1105     7027930 :     va_end(vargs);
    1106     7027930 :     return NULL;
    1107             : }
    1108             : 
    1109             : 
    1110             : PyObject *
    1111       24290 : PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
    1112             : {
    1113       24290 :     PyThreadState *tstate = _PyThreadState_GET();
    1114       24290 :     PyObject *modulename = NULL;
    1115       24290 :     PyObject *mydict = NULL;
    1116       24290 :     PyObject *bases = NULL;
    1117       24290 :     PyObject *result = NULL;
    1118             : 
    1119       24290 :     const char *dot = strrchr(name, '.');
    1120       24290 :     if (dot == NULL) {
    1121           1 :         _PyErr_SetString(tstate, PyExc_SystemError,
    1122             :                          "PyErr_NewException: name must be module.class");
    1123           1 :         return NULL;
    1124             :     }
    1125       24289 :     if (base == NULL) {
    1126       10712 :         base = PyExc_Exception;
    1127             :     }
    1128       24289 :     if (dict == NULL) {
    1129       19247 :         dict = mydict = PyDict_New();
    1130       19247 :         if (dict == NULL)
    1131           0 :             goto failure;
    1132             :     }
    1133             : 
    1134       24289 :     int r = PyDict_Contains(dict, &_Py_ID(__module__));
    1135       24289 :     if (r < 0) {
    1136           0 :         goto failure;
    1137             :     }
    1138       24289 :     if (r == 0) {
    1139       24289 :         modulename = PyUnicode_FromStringAndSize(name,
    1140             :                                              (Py_ssize_t)(dot-name));
    1141       24289 :         if (modulename == NULL)
    1142           0 :             goto failure;
    1143       24289 :         if (PyDict_SetItem(dict, &_Py_ID(__module__), modulename) != 0)
    1144           0 :             goto failure;
    1145             :     }
    1146       24289 :     if (PyTuple_Check(base)) {
    1147        4216 :         bases = base;
    1148             :         /* INCREF as we create a new ref in the else branch */
    1149        4216 :         Py_INCREF(bases);
    1150             :     } else {
    1151       20073 :         bases = PyTuple_Pack(1, base);
    1152       20073 :         if (bases == NULL)
    1153           0 :             goto failure;
    1154             :     }
    1155             :     /* Create a real class. */
    1156       24289 :     result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
    1157             :                                    dot+1, bases, dict);
    1158       24289 :   failure:
    1159       24289 :     Py_XDECREF(bases);
    1160       24289 :     Py_XDECREF(mydict);
    1161       24289 :     Py_XDECREF(modulename);
    1162       24289 :     return result;
    1163             : }
    1164             : 
    1165             : 
    1166             : /* Create an exception with docstring */
    1167             : PyObject *
    1168        5043 : PyErr_NewExceptionWithDoc(const char *name, const char *doc,
    1169             :                           PyObject *base, PyObject *dict)
    1170             : {
    1171             :     int result;
    1172        5043 :     PyObject *ret = NULL;
    1173        5043 :     PyObject *mydict = NULL; /* points to the dict only if we create it */
    1174             :     PyObject *docobj;
    1175             : 
    1176        5043 :     if (dict == NULL) {
    1177        5042 :         dict = mydict = PyDict_New();
    1178        5042 :         if (dict == NULL) {
    1179           0 :             return NULL;
    1180             :         }
    1181             :     }
    1182             : 
    1183        5043 :     if (doc != NULL) {
    1184        5040 :         docobj = PyUnicode_FromString(doc);
    1185        5040 :         if (docobj == NULL)
    1186           0 :             goto failure;
    1187        5040 :         result = PyDict_SetItemString(dict, "__doc__", docobj);
    1188        5040 :         Py_DECREF(docobj);
    1189        5040 :         if (result < 0)
    1190           0 :             goto failure;
    1191             :     }
    1192             : 
    1193        5043 :     ret = PyErr_NewException(name, base, dict);
    1194        5043 :   failure:
    1195        5043 :     Py_XDECREF(mydict);
    1196        5043 :     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        3134 : _PyErr_InitTypes(PyInterpreterState *interp)
    1226             : {
    1227        3134 :     if (!_Py_IsMainInterpreter(interp)) {
    1228         171 :         return _PyStatus_OK();
    1229             :     }
    1230             : 
    1231        2963 :     if (UnraisableHookArgsType.tp_name == NULL) {
    1232        2963 :         if (PyStructSequence_InitType2(&UnraisableHookArgsType,
    1233             :                                        &UnraisableHookArgs_desc) < 0) {
    1234           0 :             return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
    1235             :         }
    1236             :     }
    1237        2963 :     return _PyStatus_OK();
    1238             : }
    1239             : 
    1240             : 
    1241             : void
    1242        3120 : _PyErr_FiniTypes(PyInterpreterState *interp)
    1243             : {
    1244        3120 :     if (!_Py_IsMainInterpreter(interp)) {
    1245         169 :         return;
    1246             :     }
    1247             : 
    1248        2951 :     _PyStructSequence_FiniType(&UnraisableHookArgsType);
    1249             : }
    1250             : 
    1251             : 
    1252             : static PyObject *
    1253         172 : make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type,
    1254             :                           PyObject *exc_value, PyObject *exc_tb,
    1255             :                           PyObject *err_msg, PyObject *obj)
    1256             : {
    1257         172 :     PyObject *args = PyStructSequence_New(&UnraisableHookArgsType);
    1258         172 :     if (args == NULL) {
    1259          59 :         return NULL;
    1260             :     }
    1261             : 
    1262         113 :     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         113 :     ADD_ITEM(exc_type);
    1274         113 :     ADD_ITEM(exc_value);
    1275         113 :     ADD_ITEM(exc_tb);
    1276         113 :     ADD_ITEM(err_msg);
    1277         113 :     ADD_ITEM(obj);
    1278             : #undef ADD_ITEM
    1279             : 
    1280         113 :     if (_PyErr_Occurred(tstate)) {
    1281           0 :         Py_DECREF(args);
    1282           0 :         return NULL;
    1283             :     }
    1284         113 :     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         100 : 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         100 :     if (obj != NULL && obj != Py_None) {
    1300          34 :         if (err_msg != NULL && err_msg != Py_None) {
    1301          12 :             if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
    1302           0 :                 return -1;
    1303             :             }
    1304          12 :             if (PyFile_WriteString(": ", file) < 0) {
    1305           0 :                 return -1;
    1306             :             }
    1307             :         }
    1308             :         else {
    1309          22 :             if (PyFile_WriteString("Exception ignored in: ", file) < 0) {
    1310           2 :                 return -1;
    1311             :             }
    1312             :         }
    1313             : 
    1314          32 :         if (PyFile_WriteObject(obj, file, 0) < 0) {
    1315           0 :             _PyErr_Clear(tstate);
    1316           0 :             if (PyFile_WriteString("<object repr() failed>", file) < 0) {
    1317           0 :                 return -1;
    1318             :             }
    1319             :         }
    1320          32 :         if (PyFile_WriteString("\n", file) < 0) {
    1321           4 :             return -1;
    1322             :         }
    1323             :     }
    1324          66 :     else if (err_msg != NULL && err_msg != Py_None) {
    1325           3 :         if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
    1326           0 :             return -1;
    1327             :         }
    1328           3 :         if (PyFile_WriteString(":\n", file) < 0) {
    1329           0 :             return -1;
    1330             :         }
    1331             :     }
    1332             : 
    1333          94 :     if (exc_tb != NULL && exc_tb != Py_None) {
    1334          31 :         if (PyTraceBack_Print(exc_tb, file) < 0) {
    1335             :             /* continue even if writing the traceback failed */
    1336           0 :             _PyErr_Clear(tstate);
    1337             :         }
    1338             :     }
    1339             : 
    1340          94 :     if (exc_type == NULL || exc_type == Py_None) {
    1341           0 :         return -1;
    1342             :     }
    1343             : 
    1344          94 :     assert(PyExceptionClass_Check(exc_type));
    1345             : 
    1346          94 :     PyObject *modulename = PyObject_GetAttr(exc_type, &_Py_ID(__module__));
    1347          94 :     if (modulename == NULL || !PyUnicode_Check(modulename)) {
    1348           0 :         Py_XDECREF(modulename);
    1349           0 :         _PyErr_Clear(tstate);
    1350           0 :         if (PyFile_WriteString("<unknown>", file) < 0) {
    1351           0 :             return -1;
    1352             :         }
    1353             :     }
    1354             :     else {
    1355          98 :         if (!_PyUnicode_Equal(modulename, &_Py_ID(builtins)) &&
    1356           4 :             !_PyUnicode_Equal(modulename, &_Py_ID(__main__))) {
    1357           3 :             if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) {
    1358           0 :                 Py_DECREF(modulename);
    1359           0 :                 return -1;
    1360             :             }
    1361           3 :             Py_DECREF(modulename);
    1362           3 :             if (PyFile_WriteString(".", file) < 0) {
    1363           0 :                 return -1;
    1364             :             }
    1365             :         }
    1366             :         else {
    1367          91 :             Py_DECREF(modulename);
    1368             :         }
    1369             :     }
    1370             : 
    1371          94 :     PyObject *qualname = PyType_GetQualName((PyTypeObject *)exc_type);
    1372          94 :     if (qualname == NULL || !PyUnicode_Check(qualname)) {
    1373          53 :         Py_XDECREF(qualname);
    1374          53 :         _PyErr_Clear(tstate);
    1375          53 :         if (PyFile_WriteString("<unknown>", file) < 0) {
    1376          51 :             return -1;
    1377             :         }
    1378             :     }
    1379             :     else {
    1380          41 :         if (PyFile_WriteObject(qualname, file, Py_PRINT_RAW) < 0) {
    1381           0 :             Py_DECREF(qualname);
    1382           0 :             return -1;
    1383             :         }
    1384          41 :         Py_DECREF(qualname);
    1385             :     }
    1386             : 
    1387          43 :     if (exc_value && exc_value != Py_None) {
    1388          36 :         if (PyFile_WriteString(": ", file) < 0) {
    1389           0 :             return -1;
    1390             :         }
    1391          36 :         if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) {
    1392           1 :             _PyErr_Clear(tstate);
    1393           1 :             if (PyFile_WriteString("<exception str() failed>", file) < 0) {
    1394           0 :                 return -1;
    1395             :             }
    1396             :         }
    1397             :     }
    1398             : 
    1399          43 :     if (PyFile_WriteString("\n", file) < 0) {
    1400           0 :         return -1;
    1401             :     }
    1402             : 
    1403             :     /* Explicitly call file.flush() */
    1404          43 :     PyObject *res = _PyObject_CallMethodNoArgs(file, &_Py_ID(flush));
    1405          43 :     if (!res) {
    1406           0 :         return -1;
    1407             :     }
    1408          43 :     Py_DECREF(res);
    1409             : 
    1410          43 :     return 0;
    1411             : }
    1412             : 
    1413             : 
    1414             : static int
    1415         108 : write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
    1416             :                      PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
    1417             :                      PyObject *obj)
    1418             : {
    1419         108 :     PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
    1420         108 :     if (file == NULL || file == Py_None) {
    1421           8 :         return 0;
    1422             :     }
    1423             : 
    1424             :     /* Hold a strong reference to ensure that sys.stderr doesn't go away
    1425             :        while we use it */
    1426         100 :     Py_INCREF(file);
    1427         100 :     int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb,
    1428             :                                         err_msg, obj, file);
    1429         100 :     Py_DECREF(file);
    1430             : 
    1431         100 :     return res;
    1432             : }
    1433             : 
    1434             : 
    1435             : PyObject*
    1436          38 : _PyErr_WriteUnraisableDefaultHook(PyObject *args)
    1437             : {
    1438          38 :     PyThreadState *tstate = _PyThreadState_GET();
    1439             : 
    1440          38 :     if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) {
    1441           1 :         _PyErr_SetString(tstate, PyExc_TypeError,
    1442             :                          "sys.unraisablehook argument type "
    1443             :                          "must be UnraisableHookArgs");
    1444           1 :         return NULL;
    1445             :     }
    1446             : 
    1447             :     /* Borrowed references */
    1448          37 :     PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
    1449          37 :     PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
    1450          37 :     PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
    1451          37 :     PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3);
    1452          37 :     PyObject *obj = PyStructSequence_GET_ITEM(args, 4);
    1453             : 
    1454          37 :     if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) {
    1455           3 :         return NULL;
    1456             :     }
    1457          34 :     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         172 : _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
    1474             : {
    1475         172 :     PyThreadState *tstate = _PyThreadState_GET();
    1476         172 :     _Py_EnsureTstateNotNULL(tstate);
    1477             : 
    1478         172 :     PyObject *err_msg = NULL;
    1479             :     PyObject *exc_type, *exc_value, *exc_tb;
    1480         172 :     _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
    1481             : 
    1482         172 :     assert(exc_type != NULL);
    1483             : 
    1484         172 :     if (exc_type == NULL) {
    1485             :         /* sys.unraisablehook requires that at least exc_type is set */
    1486           0 :         goto default_hook;
    1487             :     }
    1488             : 
    1489         172 :     if (exc_tb == NULL) {
    1490         113 :         PyFrameObject *frame = PyThreadState_GetFrame(tstate);
    1491         113 :         if (frame != NULL) {
    1492          49 :             exc_tb = _PyTraceBack_FromFrame(NULL, frame);
    1493          49 :             if (exc_tb == NULL) {
    1494           0 :                 _PyErr_Clear(tstate);
    1495             :             }
    1496          49 :             Py_DECREF(frame);
    1497             :         }
    1498             :     }
    1499             : 
    1500         172 :     _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb);
    1501             : 
    1502         172 :     if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) {
    1503         108 :         if (PyException_SetTraceback(exc_value, exc_tb) < 0) {
    1504           0 :             _PyErr_Clear(tstate);
    1505             :         }
    1506             :     }
    1507             : 
    1508         172 :     if (err_msg_str != NULL) {
    1509          24 :         err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str);
    1510          24 :         if (err_msg == NULL) {
    1511           1 :             PyErr_Clear();
    1512             :         }
    1513             :     }
    1514             : 
    1515         172 :     PyObject *hook_args = make_unraisable_hook_args(
    1516             :         tstate, exc_type, exc_value, exc_tb, err_msg, obj);
    1517         172 :     if (hook_args == NULL) {
    1518          59 :         err_msg_str = ("Exception ignored on building "
    1519             :                        "sys.unraisablehook arguments");
    1520          59 :         goto error;
    1521             :     }
    1522             : 
    1523         113 :     PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(unraisablehook));
    1524         113 :     if (hook == NULL) {
    1525           0 :         Py_DECREF(hook_args);
    1526           0 :         goto default_hook;
    1527             :     }
    1528             : 
    1529         113 :     if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
    1530           0 :         Py_DECREF(hook_args);
    1531           0 :         err_msg_str = "Exception ignored in audit hook";
    1532           0 :         obj = NULL;
    1533           0 :         goto error;
    1534             :     }
    1535             : 
    1536         113 :     if (hook == Py_None) {
    1537           8 :         Py_DECREF(hook_args);
    1538           8 :         goto default_hook;
    1539             :     }
    1540             : 
    1541         105 :     PyObject *res = PyObject_CallOneArg(hook, hook_args);
    1542         105 :     Py_DECREF(hook_args);
    1543         105 :     if (res != NULL) {
    1544         101 :         Py_DECREF(res);
    1545         101 :         goto done;
    1546             :     }
    1547             : 
    1548             :     /* sys.unraisablehook failed: log its error using default hook */
    1549           4 :     obj = hook;
    1550           4 :     err_msg_str = NULL;
    1551             : 
    1552          63 : error:
    1553             :     /* err_msg_str and obj have been updated and we have a new exception */
    1554          63 :     Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ?
    1555             :         err_msg_str : "Exception ignored in sys.unraisablehook"));
    1556          63 :     Py_XDECREF(exc_type);
    1557          63 :     Py_XDECREF(exc_value);
    1558          63 :     Py_XDECREF(exc_tb);
    1559          63 :     _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
    1560             : 
    1561          71 : default_hook:
    1562             :     /* Call the default unraisable hook (ignore failure) */
    1563          71 :     (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb,
    1564             :                                err_msg, obj);
    1565             : 
    1566         172 : done:
    1567         172 :     Py_XDECREF(exc_type);
    1568         172 :     Py_XDECREF(exc_value);
    1569         172 :     Py_XDECREF(exc_tb);
    1570         172 :     Py_XDECREF(err_msg);
    1571         172 :     _PyErr_Clear(tstate); /* Just in case */
    1572         172 : }
    1573             : 
    1574             : 
    1575             : void
    1576         147 : PyErr_WriteUnraisable(PyObject *obj)
    1577             : {
    1578         147 :     _PyErr_WriteUnraisableMsg(NULL, obj);
    1579         147 : }
    1580             : 
    1581             : 
    1582             : void
    1583           0 : PyErr_SyntaxLocation(const char *filename, int lineno)
    1584             : {
    1585           0 :     PyErr_SyntaxLocationEx(filename, lineno, -1);
    1586           0 : }
    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         160 : 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         160 :     PyThreadState *tstate = _PyThreadState_GET();
    1599             : 
    1600             :     /* add attributes for the line number and filename for the error */
    1601         160 :     _PyErr_Fetch(tstate, &exc, &v, &tb);
    1602         160 :     _PyErr_NormalizeException(tstate, &exc, &v, &tb);
    1603             :     /* XXX check that it is, indeed, a syntax error. It might not
    1604             :      * be, though. */
    1605         160 :     tmp = PyLong_FromLong(lineno);
    1606         160 :     if (tmp == NULL)
    1607           0 :         _PyErr_Clear(tstate);
    1608             :     else {
    1609         160 :         if (PyObject_SetAttr(v, &_Py_ID(lineno), tmp)) {
    1610           0 :             _PyErr_Clear(tstate);
    1611             :         }
    1612         160 :         Py_DECREF(tmp);
    1613             :     }
    1614         160 :     tmp = NULL;
    1615         160 :     if (col_offset >= 0) {
    1616         160 :         tmp = PyLong_FromLong(col_offset);
    1617         160 :         if (tmp == NULL) {
    1618           0 :             _PyErr_Clear(tstate);
    1619             :         }
    1620             :     }
    1621         160 :     if (PyObject_SetAttr(v, &_Py_ID(offset), tmp ? tmp : Py_None)) {
    1622           0 :         _PyErr_Clear(tstate);
    1623             :     }
    1624         160 :     Py_XDECREF(tmp);
    1625             : 
    1626         160 :     tmp = NULL;
    1627         160 :     if (end_lineno >= 0) {
    1628         160 :         tmp = PyLong_FromLong(end_lineno);
    1629         160 :         if (tmp == NULL) {
    1630           0 :             _PyErr_Clear(tstate);
    1631             :         }
    1632             :     }
    1633         160 :     if (PyObject_SetAttr(v, &_Py_ID(end_lineno), tmp ? tmp : Py_None)) {
    1634           0 :         _PyErr_Clear(tstate);
    1635             :     }
    1636         160 :     Py_XDECREF(tmp);
    1637             : 
    1638         160 :     tmp = NULL;
    1639         160 :     if (end_col_offset >= 0) {
    1640         150 :         tmp = PyLong_FromLong(end_col_offset);
    1641         150 :         if (tmp == NULL) {
    1642           0 :             _PyErr_Clear(tstate);
    1643             :         }
    1644             :     }
    1645         160 :     if (PyObject_SetAttr(v, &_Py_ID(end_offset), tmp ? tmp : Py_None)) {
    1646           0 :         _PyErr_Clear(tstate);
    1647             :     }
    1648         160 :     Py_XDECREF(tmp);
    1649             : 
    1650         160 :     tmp = NULL;
    1651         160 :     if (filename != NULL) {
    1652         160 :         if (PyObject_SetAttr(v, &_Py_ID(filename), filename)) {
    1653           0 :             _PyErr_Clear(tstate);
    1654             :         }
    1655             : 
    1656         160 :         tmp = PyErr_ProgramTextObject(filename, lineno);
    1657         160 :         if (tmp) {
    1658           8 :             if (PyObject_SetAttr(v, &_Py_ID(text), tmp)) {
    1659           0 :                 _PyErr_Clear(tstate);
    1660             :             }
    1661           8 :             Py_DECREF(tmp);
    1662             :         }
    1663             :         else {
    1664         152 :             _PyErr_Clear(tstate);
    1665             :         }
    1666             :     }
    1667         160 :     if (exc != PyExc_SyntaxError) {
    1668           0 :         if (_PyObject_LookupAttr(v, &_Py_ID(msg), &tmp) < 0) {
    1669           0 :             _PyErr_Clear(tstate);
    1670             :         }
    1671           0 :         else if (tmp) {
    1672           0 :             Py_DECREF(tmp);
    1673             :         }
    1674             :         else {
    1675           0 :             tmp = PyObject_Str(v);
    1676           0 :             if (tmp) {
    1677           0 :                 if (PyObject_SetAttr(v, &_Py_ID(msg), tmp)) {
    1678           0 :                     _PyErr_Clear(tstate);
    1679             :                 }
    1680           0 :                 Py_DECREF(tmp);
    1681             :             }
    1682             :             else {
    1683           0 :                 _PyErr_Clear(tstate);
    1684             :             }
    1685             :         }
    1686             : 
    1687           0 :         if (_PyObject_LookupAttr(v, &_Py_ID(print_file_and_line), &tmp) < 0) {
    1688           0 :             _PyErr_Clear(tstate);
    1689             :         }
    1690           0 :         else if (tmp) {
    1691           0 :             Py_DECREF(tmp);
    1692             :         }
    1693             :         else {
    1694           0 :             if (PyObject_SetAttr(v, &_Py_ID(print_file_and_line), Py_None)) {
    1695           0 :                 _PyErr_Clear(tstate);
    1696             :             }
    1697             :         }
    1698             :     }
    1699         160 :     _PyErr_Restore(tstate, exc, v, tb);
    1700         160 : }
    1701             : 
    1702             : void
    1703          10 : PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) {
    1704          10 :     PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, lineno, -1);
    1705          10 : }
    1706             : 
    1707             : void
    1708         150 : PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset,
    1709             :                                  int end_lineno, int end_col_offset) {
    1710         150 :     PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, end_lineno, end_col_offset);
    1711         150 : }
    1712             : 
    1713             : void
    1714           0 : PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
    1715             : {
    1716           0 :     PyThreadState *tstate = _PyThreadState_GET();
    1717             :     PyObject *fileobj;
    1718           0 :     if (filename != NULL) {
    1719           0 :         fileobj = PyUnicode_DecodeFSDefault(filename);
    1720           0 :         if (fileobj == NULL) {
    1721           0 :             _PyErr_Clear(tstate);
    1722             :         }
    1723             :     }
    1724             :     else {
    1725           0 :         fileobj = NULL;
    1726             :     }
    1727           0 :     PyErr_SyntaxLocationObject(fileobj, lineno, col_offset);
    1728           0 :     Py_XDECREF(fileobj);
    1729           0 : }
    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          58 : err_programtext(PyThreadState *tstate, FILE *fp, int lineno, const char* encoding)
    1739             : {
    1740             :     int i;
    1741             :     char linebuf[1000];
    1742          58 :     if (fp == NULL) {
    1743           0 :         return NULL;
    1744             :     }
    1745             : 
    1746         176 :     for (i = 0; i < lineno; i++) {
    1747         118 :         char *pLastChar = &linebuf[sizeof(linebuf) - 2];
    1748             :         do {
    1749         118 :             *pLastChar = '\0';
    1750         118 :             if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf,
    1751             :                                          fp, NULL) == NULL) {
    1752           0 :                 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         118 :         } while (*pLastChar != '\0' && *pLastChar != '\n');
    1760             :     }
    1761             : 
    1762          58 : after_loop:
    1763          58 :     fclose(fp);
    1764          58 :     if (i == lineno) {
    1765             :         PyObject *res;
    1766          58 :         if (encoding != NULL) {
    1767           5 :             res = PyUnicode_Decode(linebuf, strlen(linebuf), encoding, "replace");
    1768             :         } else {
    1769          53 :             res = PyUnicode_FromString(linebuf);
    1770             :         }
    1771          58 :         if (res == NULL)
    1772           2 :             _PyErr_Clear(tstate);
    1773          58 :         return res;
    1774             :     }
    1775           0 :     return NULL;
    1776             : }
    1777             : 
    1778             : PyObject *
    1779           0 : PyErr_ProgramText(const char *filename, int lineno)
    1780             : {
    1781           0 :     if (filename == NULL) {
    1782           0 :         return NULL;
    1783             :     }
    1784             : 
    1785           0 :     PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
    1786           0 :     if (filename_obj == NULL) {
    1787           0 :         PyErr_Clear();
    1788           0 :         return NULL;
    1789             :     }
    1790           0 :     PyObject *res = PyErr_ProgramTextObject(filename_obj, lineno);
    1791           0 :     Py_DECREF(filename_obj);
    1792           0 :     return res;
    1793             : }
    1794             : 
    1795             : PyObject *
    1796        1023 : _PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* encoding)
    1797             : {
    1798        1023 :     if (filename == NULL || lineno <= 0) {
    1799           1 :         return NULL;
    1800             :     }
    1801             : 
    1802        1022 :     PyThreadState *tstate = _PyThreadState_GET();
    1803        1022 :     FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE);
    1804        1022 :     if (fp == NULL) {
    1805         964 :         _PyErr_Clear(tstate);
    1806         964 :         return NULL;
    1807             :     }
    1808          58 :     return err_programtext(tstate, fp, lineno, encoding);
    1809             : }
    1810             : 
    1811             : PyObject *
    1812         449 : PyErr_ProgramTextObject(PyObject *filename, int lineno)
    1813             : {
    1814         449 :     return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL);
    1815             : }
    1816             : 
    1817             : #ifdef __cplusplus
    1818             : }
    1819             : #endif

Generated by: LCOV version 1.14