LCOV - code coverage report
Current view: top level - Objects - exceptions.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 1221 1386 88.1 %
Date: 2022-07-20 13:12:14 Functions: 131 139 94.2 %
Branches: 699 959 72.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
       3                 :            :  *
       4                 :            :  * Thanks go to Tim Peters and Michael Hudson for debugging.
       5                 :            :  */
       6                 :            : 
       7                 :            : #define PY_SSIZE_T_CLEAN
       8                 :            : #include <Python.h>
       9                 :            : #include <stdbool.h>
      10                 :            : #include "pycore_ceval.h"         // _Py_EnterRecursiveCall
      11                 :            : #include "pycore_exceptions.h"    // struct _Py_exc_state
      12                 :            : #include "pycore_initconfig.h"
      13                 :            : #include "pycore_object.h"
      14                 :            : #include "structmember.h"         // PyMemberDef
      15                 :            : #include "osdefs.h"               // SEP
      16                 :            : 
      17                 :            : 
      18                 :            : /* Compatibility aliases */
      19                 :            : PyObject *PyExc_EnvironmentError = NULL;  // borrowed ref
      20                 :            : PyObject *PyExc_IOError = NULL;  // borrowed ref
      21                 :            : #ifdef MS_WINDOWS
      22                 :            : PyObject *PyExc_WindowsError = NULL;  // borrowed ref
      23                 :            : #endif
      24                 :            : 
      25                 :            : 
      26                 :            : static struct _Py_exc_state*
      27                 :     472948 : get_exc_state(void)
      28                 :            : {
      29                 :     472948 :     PyInterpreterState *interp = _PyInterpreterState_GET();
      30                 :     472948 :     return &interp->exc_state;
      31                 :            : }
      32                 :            : 
      33                 :            : 
      34                 :            : /* NOTE: If the exception class hierarchy changes, don't forget to update
      35                 :            :  * Lib/test/exception_hierarchy.txt
      36                 :            :  */
      37                 :            : 
      38                 :            : /*
      39                 :            :  *    BaseException
      40                 :            :  */
      41                 :            : static PyObject *
      42                 :    4777998 : BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
      43                 :            : {
      44                 :            :     PyBaseExceptionObject *self;
      45                 :            : 
      46                 :    4777998 :     self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
      47         [ +  + ]:    4777998 :     if (!self)
      48                 :          1 :         return NULL;
      49                 :            :     /* the dict is created on the fly in PyObject_GenericSetAttr */
      50                 :    4777997 :     self->dict = NULL;
      51                 :    4777997 :     self->notes = NULL;
      52                 :    4777997 :     self->traceback = self->cause = self->context = NULL;
      53                 :    4777997 :     self->suppress_context = 0;
      54                 :            : 
      55         [ +  + ]:    4777997 :     if (args) {
      56                 :    4730525 :         self->args = args;
      57                 :    4730525 :         Py_INCREF(args);
      58                 :    4730525 :         return (PyObject *)self;
      59                 :            :     }
      60                 :            : 
      61                 :      47472 :     self->args = PyTuple_New(0);
      62         [ -  + ]:      47472 :     if (!self->args) {
      63                 :          0 :         Py_DECREF(self);
      64                 :          0 :         return NULL;
      65                 :            :     }
      66                 :            : 
      67                 :      47472 :     return (PyObject *)self;
      68                 :            : }
      69                 :            : 
      70                 :            : static int
      71                 :    4688679 : BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
      72                 :            : {
      73   [ +  +  +  + ]:    4688679 :     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
      74                 :          1 :         return -1;
      75                 :            : 
      76                 :    4688678 :     Py_INCREF(args);
      77                 :    4688678 :     Py_XSETREF(self->args, args);
      78                 :            : 
      79                 :    4688678 :     return 0;
      80                 :            : }
      81                 :            : 
      82                 :            : static int
      83                 :    5147536 : BaseException_clear(PyBaseExceptionObject *self)
      84                 :            : {
      85         [ +  + ]:    5147536 :     Py_CLEAR(self->dict);
      86         [ +  + ]:    5147536 :     Py_CLEAR(self->args);
      87         [ -  + ]:    5147536 :     Py_CLEAR(self->notes);
      88         [ +  + ]:    5147536 :     Py_CLEAR(self->traceback);
      89         [ +  + ]:    5147536 :     Py_CLEAR(self->cause);
      90         [ +  + ]:    5147536 :     Py_CLEAR(self->context);
      91                 :    5147536 :     return 0;
      92                 :            : }
      93                 :            : 
      94                 :            : static void
      95                 :    1977886 : BaseException_dealloc(PyBaseExceptionObject *self)
      96                 :            : {
      97                 :    1977886 :     PyObject_GC_UnTrack(self);
      98                 :            :     // bpo-44348: The trashcan mechanism prevents stack overflow when deleting
      99                 :            :     // long chains of exceptions. For example, exceptions can be chained
     100                 :            :     // through the __context__ attributes or the __traceback__ attribute.
     101   [ +  +  +  + ]:    1977886 :     Py_TRASHCAN_BEGIN(self, BaseException_dealloc)
     102                 :    1977372 :     BaseException_clear(self);
     103                 :    1977372 :     Py_TYPE(self)->tp_free((PyObject *)self);
     104         [ +  + ]:    1977372 :     Py_TRASHCAN_END
     105                 :    1977886 : }
     106                 :            : 
     107                 :            : static int
     108                 :     100241 : BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
     109                 :            : {
     110   [ +  +  -  + ]:     100241 :     Py_VISIT(self->dict);
     111   [ +  -  -  + ]:     100241 :     Py_VISIT(self->args);
     112   [ -  +  -  - ]:     100241 :     Py_VISIT(self->notes);
     113   [ +  +  -  + ]:     100241 :     Py_VISIT(self->traceback);
     114   [ +  +  -  + ]:     100241 :     Py_VISIT(self->cause);
     115   [ +  +  -  + ]:     100241 :     Py_VISIT(self->context);
     116                 :     100241 :     return 0;
     117                 :            : }
     118                 :            : 
     119                 :            : static PyObject *
     120                 :      20530 : BaseException_str(PyBaseExceptionObject *self)
     121                 :            : {
     122      [ +  +  + ]:      20530 :     switch (PyTuple_GET_SIZE(self->args)) {
     123                 :        210 :     case 0:
     124                 :        210 :         return PyUnicode_FromString("");
     125                 :      20301 :     case 1:
     126                 :      20301 :         return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
     127                 :         19 :     default:
     128                 :         19 :         return PyObject_Str(self->args);
     129                 :            :     }
     130                 :            : }
     131                 :            : 
     132                 :            : static PyObject *
     133                 :       2376 : BaseException_repr(PyBaseExceptionObject *self)
     134                 :            : {
     135                 :       2376 :     const char *name = _PyType_Name(Py_TYPE(self));
     136         [ +  + ]:       2376 :     if (PyTuple_GET_SIZE(self->args) == 1)
     137                 :       1795 :         return PyUnicode_FromFormat("%s(%R)", name,
     138                 :       1795 :                                     PyTuple_GET_ITEM(self->args, 0));
     139                 :            :     else
     140                 :        581 :         return PyUnicode_FromFormat("%s%R", name, self->args);
     141                 :            : }
     142                 :            : 
     143                 :            : /* Pickling support */
     144                 :            : static PyObject *
     145                 :        320 : BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
     146                 :            : {
     147   [ +  -  +  + ]:        320 :     if (self->args && self->dict)
     148                 :        100 :         return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
     149                 :            :     else
     150                 :        220 :         return PyTuple_Pack(2, Py_TYPE(self), self->args);
     151                 :            : }
     152                 :            : 
     153                 :            : /*
     154                 :            :  * Needed for backward compatibility, since exceptions used to store
     155                 :            :  * all their attributes in the __dict__. Code is taken from cPickle's
     156                 :            :  * load_build function.
     157                 :            :  */
     158                 :            : static PyObject *
     159                 :        167 : BaseException_setstate(PyObject *self, PyObject *state)
     160                 :            : {
     161                 :            :     PyObject *d_key, *d_value;
     162                 :        167 :     Py_ssize_t i = 0;
     163                 :            : 
     164         [ +  - ]:        167 :     if (state != Py_None) {
     165         [ +  + ]:        167 :         if (!PyDict_Check(state)) {
     166                 :          1 :             PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
     167                 :          1 :             return NULL;
     168                 :            :         }
     169         [ +  + ]:        559 :         while (PyDict_Next(state, &i, &d_key, &d_value)) {
     170         [ -  + ]:        393 :             if (PyObject_SetAttr(self, d_key, d_value) < 0)
     171                 :          0 :                 return NULL;
     172                 :            :         }
     173                 :            :     }
     174                 :        166 :     Py_RETURN_NONE;
     175                 :            : }
     176                 :            : 
     177                 :            : static PyObject *
     178                 :     188040 : BaseException_with_traceback(PyObject *self, PyObject *tb) {
     179         [ -  + ]:     188040 :     if (PyException_SetTraceback(self, tb))
     180                 :          0 :         return NULL;
     181                 :            : 
     182                 :     188040 :     Py_INCREF(self);
     183                 :     188040 :     return self;
     184                 :            : }
     185                 :            : 
     186                 :            : PyDoc_STRVAR(with_traceback_doc,
     187                 :            : "Exception.with_traceback(tb) --\n\
     188                 :            :     set self.__traceback__ to tb and return self.");
     189                 :            : 
     190                 :            : static inline PyBaseExceptionObject*
     191                 :   59000239 : _PyBaseExceptionObject_cast(PyObject *exc)
     192                 :            : {
     193                 :            :     assert(PyExceptionInstance_Check(exc));
     194                 :   59000239 :     return (PyBaseExceptionObject *)exc;
     195                 :            : }
     196                 :            : 
     197                 :            : static PyObject *
     198                 :         57 : BaseException_add_note(PyObject *self, PyObject *note)
     199                 :            : {
     200         [ +  + ]:         57 :     if (!PyUnicode_Check(note)) {
     201                 :          3 :         PyErr_Format(PyExc_TypeError,
     202                 :            :                      "note must be a str, not '%s'",
     203                 :          3 :                      Py_TYPE(note)->tp_name);
     204                 :          3 :         return NULL;
     205                 :            :     }
     206                 :            : 
     207         [ +  + ]:         54 :     if (!PyObject_HasAttr(self, &_Py_ID(__notes__))) {
     208                 :         32 :         PyObject *new_notes = PyList_New(0);
     209         [ -  + ]:         32 :         if (new_notes == NULL) {
     210                 :          0 :             return NULL;
     211                 :            :         }
     212         [ -  + ]:         32 :         if (PyObject_SetAttr(self, &_Py_ID(__notes__), new_notes) < 0) {
     213                 :          0 :             Py_DECREF(new_notes);
     214                 :          0 :             return NULL;
     215                 :            :         }
     216                 :         32 :         Py_DECREF(new_notes);
     217                 :            :     }
     218                 :         54 :     PyObject *notes = PyObject_GetAttr(self, &_Py_ID(__notes__));
     219         [ -  + ]:         54 :     if (notes == NULL) {
     220                 :          0 :         return NULL;
     221                 :            :     }
     222         [ +  + ]:         54 :     if (!PyList_Check(notes)) {
     223                 :          3 :         Py_DECREF(notes);
     224                 :          3 :         PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list");
     225                 :          3 :         return NULL;
     226                 :            :     }
     227         [ -  + ]:         51 :     if (PyList_Append(notes, note) < 0) {
     228                 :          0 :         Py_DECREF(notes);
     229                 :          0 :         return NULL;
     230                 :            :     }
     231                 :         51 :     Py_DECREF(notes);
     232                 :         51 :     Py_RETURN_NONE;
     233                 :            : }
     234                 :            : 
     235                 :            : PyDoc_STRVAR(add_note_doc,
     236                 :            : "Exception.add_note(note) --\n\
     237                 :            :     add a note to the exception");
     238                 :            : 
     239                 :            : static PyMethodDef BaseException_methods[] = {
     240                 :            :    {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
     241                 :            :    {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
     242                 :            :    {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
     243                 :            :     with_traceback_doc},
     244                 :            :    {"add_note", (PyCFunction)BaseException_add_note, METH_O,
     245                 :            :     add_note_doc},
     246                 :            :    {NULL, NULL, 0, NULL},
     247                 :            : };
     248                 :            : 
     249                 :            : static PyObject *
     250                 :       2495 : BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
     251                 :            : {
     252         [ -  + ]:       2495 :     if (self->args == NULL) {
     253                 :          0 :         Py_RETURN_NONE;
     254                 :            :     }
     255                 :       2495 :     Py_INCREF(self->args);
     256                 :       2495 :     return self->args;
     257                 :            : }
     258                 :            : 
     259                 :            : static int
     260                 :      30714 : BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored))
     261                 :            : {
     262                 :            :     PyObject *seq;
     263         [ +  + ]:      30714 :     if (val == NULL) {
     264                 :          1 :         PyErr_SetString(PyExc_TypeError, "args may not be deleted");
     265                 :          1 :         return -1;
     266                 :            :     }
     267                 :      30713 :     seq = PySequence_Tuple(val);
     268         [ +  + ]:      30713 :     if (!seq)
     269                 :          1 :         return -1;
     270                 :      30712 :     Py_XSETREF(self->args, seq);
     271                 :      30712 :     return 0;
     272                 :            : }
     273                 :            : 
     274                 :            : static PyObject *
     275                 :      18301 : BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
     276                 :            : {
     277         [ +  + ]:      18301 :     if (self->traceback == NULL) {
     278                 :      10301 :         Py_RETURN_NONE;
     279                 :            :     }
     280                 :       8000 :     Py_INCREF(self->traceback);
     281                 :       8000 :     return self->traceback;
     282                 :            : }
     283                 :            : 
     284                 :            : static int
     285                 :    4485257 : BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
     286                 :            : {
     287         [ +  + ]:    4485257 :     if (tb == NULL) {
     288                 :          1 :         PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
     289                 :          1 :         return -1;
     290                 :            :     }
     291   [ +  +  +  + ]:    4485256 :     else if (!(tb == Py_None || PyTraceBack_Check(tb))) {
     292                 :          2 :         PyErr_SetString(PyExc_TypeError,
     293                 :            :                         "__traceback__ must be a traceback or None");
     294                 :          2 :         return -1;
     295                 :            :     }
     296                 :            : 
     297                 :    4485254 :     Py_INCREF(tb);
     298                 :    4485254 :     Py_XSETREF(self->traceback, tb);
     299                 :    4485254 :     return 0;
     300                 :            : }
     301                 :            : 
     302                 :            : static PyObject *
     303                 :      19657 : BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored))
     304                 :            : {
     305                 :      19657 :     PyObject *res = PyException_GetContext(self);
     306         [ +  + ]:      19657 :     if (res)
     307                 :       6494 :         return res;  /* new reference already returned above */
     308                 :      13163 :     Py_RETURN_NONE;
     309                 :            : }
     310                 :            : 
     311                 :            : static int
     312                 :        131 : BaseException_set_context(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
     313                 :            : {
     314         [ +  + ]:        131 :     if (arg == NULL) {
     315                 :          1 :         PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
     316                 :          1 :         return -1;
     317         [ +  + ]:        130 :     } else if (arg == Py_None) {
     318                 :        100 :         arg = NULL;
     319         [ +  + ]:         30 :     } else if (!PyExceptionInstance_Check(arg)) {
     320                 :          1 :         PyErr_SetString(PyExc_TypeError, "exception context must be None "
     321                 :            :                         "or derive from BaseException");
     322                 :          1 :         return -1;
     323                 :            :     } else {
     324                 :            :         /* PyException_SetContext steals this reference */
     325                 :         29 :         Py_INCREF(arg);
     326                 :            :     }
     327                 :        129 :     PyException_SetContext(self, arg);
     328                 :        129 :     return 0;
     329                 :            : }
     330                 :            : 
     331                 :            : static PyObject *
     332                 :      14010 : BaseException_get_cause(PyObject *self, void *Py_UNUSED(ignored))
     333                 :            : {
     334                 :      14010 :     PyObject *res = PyException_GetCause(self);
     335         [ +  + ]:      14010 :     if (res)
     336                 :        210 :         return res;  /* new reference already returned above */
     337                 :      13800 :     Py_RETURN_NONE;
     338                 :            : }
     339                 :            : 
     340                 :            : static int
     341                 :        298 : BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
     342                 :            : {
     343         [ +  + ]:        298 :     if (arg == NULL) {
     344                 :          1 :         PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
     345                 :          1 :         return -1;
     346         [ +  + ]:        297 :     } else if (arg == Py_None) {
     347                 :          1 :         arg = NULL;
     348         [ +  + ]:        296 :     } else if (!PyExceptionInstance_Check(arg)) {
     349                 :          1 :         PyErr_SetString(PyExc_TypeError, "exception cause must be None "
     350                 :            :                         "or derive from BaseException");
     351                 :          1 :         return -1;
     352                 :            :     } else {
     353                 :            :         /* PyException_SetCause steals this reference */
     354                 :        295 :         Py_INCREF(arg);
     355                 :            :     }
     356                 :        296 :     PyException_SetCause(self, arg);
     357                 :        296 :     return 0;
     358                 :            : }
     359                 :            : 
     360                 :            : 
     361                 :            : static PyGetSetDef BaseException_getset[] = {
     362                 :            :     {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
     363                 :            :     {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
     364                 :            :     {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
     365                 :            :     {"__context__", BaseException_get_context,
     366                 :            :      BaseException_set_context, PyDoc_STR("exception context")},
     367                 :            :     {"__cause__", BaseException_get_cause,
     368                 :            :      BaseException_set_cause, PyDoc_STR("exception cause")},
     369                 :            :     {NULL},
     370                 :            : };
     371                 :            : 
     372                 :            : 
     373                 :            : PyObject *
     374                 :    1898840 : PyException_GetTraceback(PyObject *self)
     375                 :            : {
     376                 :    1898840 :     PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
     377                 :    1898840 :     Py_XINCREF(base_self->traceback);
     378                 :    1898840 :     return base_self->traceback;
     379                 :            : }
     380                 :            : 
     381                 :            : 
     382                 :            : int
     383                 :    4483147 : PyException_SetTraceback(PyObject *self, PyObject *tb)
     384                 :            : {
     385                 :    4483147 :     return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
     386                 :            : }
     387                 :            : 
     388                 :            : PyObject *
     389                 :      14857 : PyException_GetCause(PyObject *self)
     390                 :            : {
     391                 :      14857 :     PyObject *cause = _PyBaseExceptionObject_cast(self)->cause;
     392                 :      14857 :     Py_XINCREF(cause);
     393                 :      14857 :     return cause;
     394                 :            : }
     395                 :            : 
     396                 :            : /* Steals a reference to cause */
     397                 :            : void
     398                 :      68854 : PyException_SetCause(PyObject *self, PyObject *cause)
     399                 :            : {
     400                 :      68854 :     PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
     401                 :      68854 :     base_self->suppress_context = 1;
     402                 :      68854 :     Py_XSETREF(base_self->cause, cause);
     403                 :      68854 : }
     404                 :            : 
     405                 :            : PyObject *
     406                 :   51593737 : PyException_GetContext(PyObject *self)
     407                 :            : {
     408                 :   51593737 :     PyObject *context = _PyBaseExceptionObject_cast(self)->context;
     409                 :   51593737 :     Py_XINCREF(context);
     410                 :   51593737 :     return context;
     411                 :            : }
     412                 :            : 
     413                 :            : /* Steals a reference to context */
     414                 :            : void
     415                 :     470402 : PyException_SetContext(PyObject *self, PyObject *context)
     416                 :            : {
     417                 :     470402 :     Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context);
     418                 :     470402 : }
     419                 :            : 
     420                 :            : const char *
     421                 :          0 : PyExceptionClass_Name(PyObject *ob)
     422                 :            : {
     423                 :            :     assert(PyExceptionClass_Check(ob));
     424                 :          0 :     return ((PyTypeObject*)ob)->tp_name;
     425                 :            : }
     426                 :            : 
     427                 :            : static struct PyMemberDef BaseException_members[] = {
     428                 :            :     {"__suppress_context__", T_BOOL,
     429                 :            :      offsetof(PyBaseExceptionObject, suppress_context)},
     430                 :            :     {NULL}
     431                 :            : };
     432                 :            : 
     433                 :            : 
     434                 :            : static PyTypeObject _PyExc_BaseException = {
     435                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
     436                 :            :     "BaseException", /*tp_name*/
     437                 :            :     sizeof(PyBaseExceptionObject), /*tp_basicsize*/
     438                 :            :     0,                          /*tp_itemsize*/
     439                 :            :     (destructor)BaseException_dealloc, /*tp_dealloc*/
     440                 :            :     0,                          /*tp_vectorcall_offset*/
     441                 :            :     0,                          /*tp_getattr*/
     442                 :            :     0,                          /*tp_setattr*/
     443                 :            :     0,                          /*tp_as_async*/
     444                 :            :     (reprfunc)BaseException_repr, /*tp_repr*/
     445                 :            :     0,                          /*tp_as_number*/
     446                 :            :     0,                          /*tp_as_sequence*/
     447                 :            :     0,                          /*tp_as_mapping*/
     448                 :            :     0,                          /*tp_hash */
     449                 :            :     0,                          /*tp_call*/
     450                 :            :     (reprfunc)BaseException_str,  /*tp_str*/
     451                 :            :     PyObject_GenericGetAttr,    /*tp_getattro*/
     452                 :            :     PyObject_GenericSetAttr,    /*tp_setattro*/
     453                 :            :     0,                          /*tp_as_buffer*/
     454                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
     455                 :            :         Py_TPFLAGS_BASE_EXC_SUBCLASS,  /*tp_flags*/
     456                 :            :     PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
     457                 :            :     (traverseproc)BaseException_traverse, /* tp_traverse */
     458                 :            :     (inquiry)BaseException_clear, /* tp_clear */
     459                 :            :     0,                          /* tp_richcompare */
     460                 :            :     0,                          /* tp_weaklistoffset */
     461                 :            :     0,                          /* tp_iter */
     462                 :            :     0,                          /* tp_iternext */
     463                 :            :     BaseException_methods,      /* tp_methods */
     464                 :            :     BaseException_members,      /* tp_members */
     465                 :            :     BaseException_getset,       /* tp_getset */
     466                 :            :     0,                          /* tp_base */
     467                 :            :     0,                          /* tp_dict */
     468                 :            :     0,                          /* tp_descr_get */
     469                 :            :     0,                          /* tp_descr_set */
     470                 :            :     offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
     471                 :            :     (initproc)BaseException_init, /* tp_init */
     472                 :            :     0,                          /* tp_alloc */
     473                 :            :     BaseException_new,          /* tp_new */
     474                 :            : };
     475                 :            : /* the CPython API expects exceptions to be (PyObject *) - both a hold-over
     476                 :            : from the previous implementation and also allowing Python objects to be used
     477                 :            : in the API */
     478                 :            : PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
     479                 :            : 
     480                 :            : /* note these macros omit the last semicolon so the macro invocation may
     481                 :            :  * include it and not look strange.
     482                 :            :  */
     483                 :            : #define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
     484                 :            : static PyTypeObject _PyExc_ ## EXCNAME = { \
     485                 :            :     PyVarObject_HEAD_INIT(NULL, 0) \
     486                 :            :     # EXCNAME, \
     487                 :            :     sizeof(PyBaseExceptionObject), \
     488                 :            :     0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
     489                 :            :     0, 0, 0, 0, 0, 0, 0, \
     490                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
     491                 :            :     PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
     492                 :            :     (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
     493                 :            :     0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
     494                 :            :     (initproc)BaseException_init, 0, BaseException_new,\
     495                 :            : }; \
     496                 :            : PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
     497                 :            : 
     498                 :            : #define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
     499                 :            : static PyTypeObject _PyExc_ ## EXCNAME = { \
     500                 :            :     PyVarObject_HEAD_INIT(NULL, 0) \
     501                 :            :     # EXCNAME, \
     502                 :            :     sizeof(Py ## EXCSTORE ## Object), \
     503                 :            :     0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     504                 :            :     0, 0, 0, 0, 0, \
     505                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
     506                 :            :     PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
     507                 :            :     (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
     508                 :            :     0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
     509                 :            :     (initproc)EXCSTORE ## _init, 0, 0, \
     510                 :            : }; \
     511                 :            : PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
     512                 :            : 
     513                 :            : #define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \
     514                 :            :                                 EXCMETHODS, EXCMEMBERS, EXCGETSET, \
     515                 :            :                                 EXCSTR, EXCDOC) \
     516                 :            : static PyTypeObject _PyExc_ ## EXCNAME = { \
     517                 :            :     PyVarObject_HEAD_INIT(NULL, 0) \
     518                 :            :     # EXCNAME, \
     519                 :            :     sizeof(Py ## EXCSTORE ## Object), 0, \
     520                 :            :     (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     521                 :            :     (reprfunc)EXCSTR, 0, 0, 0, \
     522                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
     523                 :            :     PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
     524                 :            :     (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
     525                 :            :     EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \
     526                 :            :     0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
     527                 :            :     (initproc)EXCSTORE ## _init, 0, EXCNEW,\
     528                 :            : }; \
     529                 :            : PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
     530                 :            : 
     531                 :            : 
     532                 :            : /*
     533                 :            :  *    Exception extends BaseException
     534                 :            :  */
     535                 :            : SimpleExtendsException(PyExc_BaseException, Exception,
     536                 :            :                        "Common base class for all non-exit exceptions.");
     537                 :            : 
     538                 :            : 
     539                 :            : /*
     540                 :            :  *    TypeError extends Exception
     541                 :            :  */
     542                 :            : SimpleExtendsException(PyExc_Exception, TypeError,
     543                 :            :                        "Inappropriate argument type.");
     544                 :            : 
     545                 :            : 
     546                 :            : /*
     547                 :            :  *    StopAsyncIteration extends Exception
     548                 :            :  */
     549                 :            : SimpleExtendsException(PyExc_Exception, StopAsyncIteration,
     550                 :            :                        "Signal the end from iterator.__anext__().");
     551                 :            : 
     552                 :            : 
     553                 :            : /*
     554                 :            :  *    StopIteration extends Exception
     555                 :            :  */
     556                 :            : 
     557                 :            : static PyMemberDef StopIteration_members[] = {
     558                 :            :     {"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0,
     559                 :            :         PyDoc_STR("generator return value")},
     560                 :            :     {NULL}  /* Sentinel */
     561                 :            : };
     562                 :            : 
     563                 :            : static int
     564                 :    1159814 : StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds)
     565                 :            : {
     566                 :    1159814 :     Py_ssize_t size = PyTuple_GET_SIZE(args);
     567                 :            :     PyObject *value;
     568                 :            : 
     569         [ -  + ]:    1159814 :     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
     570                 :          0 :         return -1;
     571         [ -  + ]:    1159814 :     Py_CLEAR(self->value);
     572         [ +  + ]:    1159814 :     if (size > 0)
     573                 :        844 :         value = PyTuple_GET_ITEM(args, 0);
     574                 :            :     else
     575                 :    1158970 :         value = Py_None;
     576                 :    1159814 :     Py_INCREF(value);
     577                 :    1159814 :     self->value = value;
     578                 :    1159814 :     return 0;
     579                 :            : }
     580                 :            : 
     581                 :            : static int
     582                 :    1159817 : StopIteration_clear(PyStopIterationObject *self)
     583                 :            : {
     584         [ +  + ]:    1159817 :     Py_CLEAR(self->value);
     585                 :    1159817 :     return BaseException_clear((PyBaseExceptionObject *)self);
     586                 :            : }
     587                 :            : 
     588                 :            : static void
     589                 :    1159814 : StopIteration_dealloc(PyStopIterationObject *self)
     590                 :            : {
     591                 :    1159814 :     PyObject_GC_UnTrack(self);
     592                 :    1159814 :     StopIteration_clear(self);
     593                 :    1159814 :     Py_TYPE(self)->tp_free((PyObject *)self);
     594                 :    1159814 : }
     595                 :            : 
     596                 :            : static int
     597                 :         58 : StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg)
     598                 :            : {
     599   [ +  -  -  + ]:         58 :     Py_VISIT(self->value);
     600                 :         58 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
     601                 :            : }
     602                 :            : 
     603                 :            : ComplexExtendsException(PyExc_Exception, StopIteration, StopIteration,
     604                 :            :                         0, 0, StopIteration_members, 0, 0,
     605                 :            :                         "Signal the end from iterator.__next__().");
     606                 :            : 
     607                 :            : 
     608                 :            : /*
     609                 :            :  *    GeneratorExit extends BaseException
     610                 :            :  */
     611                 :            : SimpleExtendsException(PyExc_BaseException, GeneratorExit,
     612                 :            :                        "Request that a generator exit.");
     613                 :            : 
     614                 :            : 
     615                 :            : /*
     616                 :            :  *    SystemExit extends BaseException
     617                 :            :  */
     618                 :            : 
     619                 :            : static int
     620                 :       3648 : SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
     621                 :            : {
     622                 :       3648 :     Py_ssize_t size = PyTuple_GET_SIZE(args);
     623                 :            : 
     624         [ -  + ]:       3648 :     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
     625                 :          0 :         return -1;
     626                 :            : 
     627         [ +  + ]:       3648 :     if (size == 0)
     628                 :         65 :         return 0;
     629         [ +  + ]:       3583 :     if (size == 1) {
     630                 :       3582 :         Py_INCREF(PyTuple_GET_ITEM(args, 0));
     631                 :       3582 :         Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0));
     632                 :            :     }
     633                 :            :     else { /* size > 1 */
     634                 :          1 :         Py_INCREF(args);
     635                 :          1 :         Py_XSETREF(self->code, args);
     636                 :            :     }
     637                 :       3583 :     return 0;
     638                 :            : }
     639                 :            : 
     640                 :            : static int
     641                 :       3652 : SystemExit_clear(PySystemExitObject *self)
     642                 :            : {
     643         [ +  + ]:       3652 :     Py_CLEAR(self->code);
     644                 :       3652 :     return BaseException_clear((PyBaseExceptionObject *)self);
     645                 :            : }
     646                 :            : 
     647                 :            : static void
     648                 :       3648 : SystemExit_dealloc(PySystemExitObject *self)
     649                 :            : {
     650                 :       3648 :     _PyObject_GC_UNTRACK(self);
     651                 :       3648 :     SystemExit_clear(self);
     652                 :       3648 :     Py_TYPE(self)->tp_free((PyObject *)self);
     653                 :       3648 : }
     654                 :            : 
     655                 :            : static int
     656                 :        108 : SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
     657                 :            : {
     658   [ +  +  -  + ]:        108 :     Py_VISIT(self->code);
     659                 :        108 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
     660                 :            : }
     661                 :            : 
     662                 :            : static PyMemberDef SystemExit_members[] = {
     663                 :            :     {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
     664                 :            :         PyDoc_STR("exception code")},
     665                 :            :     {NULL}  /* Sentinel */
     666                 :            : };
     667                 :            : 
     668                 :            : ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
     669                 :            :                         0, 0, SystemExit_members, 0, 0,
     670                 :            :                         "Request to exit from the interpreter.");
     671                 :            : 
     672                 :            : /*
     673                 :            :  *    BaseExceptionGroup extends BaseException
     674                 :            :  *    ExceptionGroup extends BaseExceptionGroup and Exception
     675                 :            :  */
     676                 :            : 
     677                 :            : 
     678                 :            : static inline PyBaseExceptionGroupObject*
     679                 :      13613 : _PyBaseExceptionGroupObject_cast(PyObject *exc)
     680                 :            : {
     681                 :            :     assert(_PyBaseExceptionGroup_Check(exc));
     682                 :      13613 :     return (PyBaseExceptionGroupObject *)exc;
     683                 :            : }
     684                 :            : 
     685                 :            : static PyObject *
     686                 :      10770 : BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     687                 :            : {
     688                 :      10770 :     struct _Py_exc_state *state = get_exc_state();
     689                 :      10770 :     PyTypeObject *PyExc_ExceptionGroup =
     690                 :            :         (PyTypeObject*)state->PyExc_ExceptionGroup;
     691                 :            : 
     692                 :      10770 :     PyObject *message = NULL;
     693                 :      10770 :     PyObject *exceptions = NULL;
     694                 :            : 
     695         [ +  + ]:      10770 :     if (!PyArg_ParseTuple(args,
     696                 :            :                           "UO:BaseExceptionGroup.__new__",
     697                 :            :                           &message,
     698                 :            :                           &exceptions)) {
     699                 :          7 :         return NULL;
     700                 :            :     }
     701                 :            : 
     702         [ +  + ]:      10763 :     if (!PySequence_Check(exceptions)) {
     703                 :          2 :         PyErr_SetString(
     704                 :            :             PyExc_TypeError,
     705                 :            :             "second argument (exceptions) must be a sequence");
     706                 :          2 :         return NULL;
     707                 :            :     }
     708                 :            : 
     709                 :      10761 :     exceptions = PySequence_Tuple(exceptions);
     710         [ -  + ]:      10761 :     if (!exceptions) {
     711                 :          0 :         return NULL;
     712                 :            :     }
     713                 :            : 
     714                 :            :     /* We are now holding a ref to the exceptions tuple */
     715                 :            : 
     716                 :      10761 :     Py_ssize_t numexcs = PyTuple_GET_SIZE(exceptions);
     717         [ +  + ]:      10761 :     if (numexcs == 0) {
     718                 :          1 :         PyErr_SetString(
     719                 :            :             PyExc_ValueError,
     720                 :            :             "second argument (exceptions) must be a non-empty sequence");
     721                 :          1 :         goto error;
     722                 :            :     }
     723                 :            : 
     724                 :      10760 :     bool nested_base_exceptions = false;
     725         [ +  + ]:      27933 :     for (Py_ssize_t i = 0; i < numexcs; i++) {
     726                 :      17175 :         PyObject *exc = PyTuple_GET_ITEM(exceptions, i);
     727         [ -  + ]:      17175 :         if (!exc) {
     728                 :          0 :             goto error;
     729                 :            :         }
     730         [ +  + ]:      17175 :         if (!PyExceptionInstance_Check(exc)) {
     731                 :          2 :             PyErr_Format(
     732                 :            :                 PyExc_ValueError,
     733                 :            :                 "Item %d of second argument (exceptions) is not an exception",
     734                 :            :                 i);
     735                 :          2 :             goto error;
     736                 :            :         }
     737                 :      17173 :         int is_nonbase_exception = PyObject_IsInstance(exc, PyExc_Exception);
     738         [ -  + ]:      17173 :         if (is_nonbase_exception < 0) {
     739                 :          0 :             goto error;
     740                 :            :         }
     741         [ +  + ]:      17173 :         else if (is_nonbase_exception == 0) {
     742                 :         23 :             nested_base_exceptions = true;
     743                 :            :         }
     744                 :            :     }
     745                 :            : 
     746                 :      10758 :     PyTypeObject *cls = type;
     747         [ +  + ]:      10758 :     if (cls == PyExc_ExceptionGroup) {
     748         [ +  + ]:      10229 :         if (nested_base_exceptions) {
     749                 :          1 :             PyErr_SetString(PyExc_TypeError,
     750                 :            :                 "Cannot nest BaseExceptions in an ExceptionGroup");
     751                 :          1 :             goto error;
     752                 :            :         }
     753                 :            :     }
     754         [ +  + ]:        529 :     else if (cls == (PyTypeObject*)PyExc_BaseExceptionGroup) {
     755         [ +  + ]:        486 :         if (!nested_base_exceptions) {
     756                 :            :             /* All nested exceptions are Exception subclasses,
     757                 :            :              * wrap them in an ExceptionGroup
     758                 :            :              */
     759                 :        468 :             cls = PyExc_ExceptionGroup;
     760                 :            :         }
     761                 :            :     }
     762                 :            :     else {
     763                 :            :         /* Do nothing - we don't interfere with subclasses */
     764                 :            :     }
     765                 :            : 
     766         [ -  + ]:      10757 :     if (!cls) {
     767                 :            :         /* Don't crash during interpreter shutdown
     768                 :            :          * (PyExc_ExceptionGroup may have been cleared)
     769                 :            :          */
     770                 :          0 :         cls = (PyTypeObject*)PyExc_BaseExceptionGroup;
     771                 :            :     }
     772                 :            :     PyBaseExceptionGroupObject *self =
     773                 :      10757 :         _PyBaseExceptionGroupObject_cast(BaseException_new(cls, args, kwds));
     774         [ -  + ]:      10757 :     if (!self) {
     775                 :          0 :         goto error;
     776                 :            :     }
     777                 :            : 
     778                 :      10757 :     self->msg = Py_NewRef(message);
     779                 :      10757 :     self->excs = exceptions;
     780                 :      10757 :     return (PyObject*)self;
     781                 :          4 : error:
     782                 :          4 :     Py_DECREF(exceptions);
     783                 :          4 :     return NULL;
     784                 :            : }
     785                 :            : 
     786                 :            : PyObject *
     787                 :         50 : _PyExc_CreateExceptionGroup(const char *msg_str, PyObject *excs)
     788                 :            : {
     789                 :         50 :     PyObject *msg = PyUnicode_FromString(msg_str);
     790         [ -  + ]:         50 :     if (!msg) {
     791                 :          0 :         return NULL;
     792                 :            :     }
     793                 :         50 :     PyObject *args = PyTuple_Pack(2, msg, excs);
     794                 :         50 :     Py_DECREF(msg);
     795         [ -  + ]:         50 :     if (!args) {
     796                 :          0 :         return NULL;
     797                 :            :     }
     798                 :         50 :     PyObject *result = PyObject_CallObject(PyExc_BaseExceptionGroup, args);
     799                 :         50 :     Py_DECREF(args);
     800                 :         50 :     return result;
     801                 :            : }
     802                 :            : 
     803                 :            : static int
     804                 :      10757 : BaseExceptionGroup_init(PyBaseExceptionGroupObject *self,
     805                 :            :     PyObject *args, PyObject *kwds)
     806                 :            : {
     807   [ -  +  -  - ]:      10757 :     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) {
     808                 :          0 :         return -1;
     809                 :            :     }
     810         [ -  + ]:      10757 :     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) {
     811                 :          0 :         return -1;
     812                 :            :     }
     813                 :      10757 :     return 0;
     814                 :            : }
     815                 :            : 
     816                 :            : static int
     817                 :      10889 : BaseExceptionGroup_clear(PyBaseExceptionGroupObject *self)
     818                 :            : {
     819         [ +  + ]:      10889 :     Py_CLEAR(self->msg);
     820         [ +  + ]:      10889 :     Py_CLEAR(self->excs);
     821                 :      10889 :     return BaseException_clear((PyBaseExceptionObject *)self);
     822                 :            : }
     823                 :            : 
     824                 :            : static void
     825                 :      10757 : BaseExceptionGroup_dealloc(PyBaseExceptionGroupObject *self)
     826                 :            : {
     827                 :      10757 :     _PyObject_GC_UNTRACK(self);
     828                 :      10757 :     BaseExceptionGroup_clear(self);
     829                 :      10757 :     Py_TYPE(self)->tp_free((PyObject *)self);
     830                 :      10757 : }
     831                 :            : 
     832                 :            : static int
     833                 :      28100 : BaseExceptionGroup_traverse(PyBaseExceptionGroupObject *self,
     834                 :            :      visitproc visit, void *arg)
     835                 :            : {
     836   [ +  -  -  + ]:      28100 :     Py_VISIT(self->msg);
     837   [ +  -  -  + ]:      28100 :     Py_VISIT(self->excs);
     838                 :      28100 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
     839                 :            : }
     840                 :            : 
     841                 :            : static PyObject *
     842                 :       4083 : BaseExceptionGroup_str(PyBaseExceptionGroupObject *self)
     843                 :            : {
     844                 :            :     assert(self->msg);
     845                 :            :     assert(PyUnicode_Check(self->msg));
     846                 :            : 
     847                 :            :     assert(PyTuple_CheckExact(self->excs));
     848                 :       4083 :     Py_ssize_t num_excs = PyTuple_Size(self->excs);
     849         [ +  + ]:       4083 :     return PyUnicode_FromFormat(
     850                 :            :         "%S (%zd sub-exception%s)",
     851                 :            :         self->msg, num_excs, num_excs > 1 ? "s" : "");
     852                 :            : }
     853                 :            : 
     854                 :            : static PyObject *
     855                 :        416 : BaseExceptionGroup_derive(PyObject *self_, PyObject *args)
     856                 :            : {
     857                 :        416 :     PyBaseExceptionGroupObject *self = _PyBaseExceptionGroupObject_cast(self_);
     858                 :        416 :     PyObject *excs = NULL;
     859         [ -  + ]:        416 :     if (!PyArg_ParseTuple(args, "O", &excs)) {
     860                 :          0 :         return NULL;
     861                 :            :     }
     862                 :        416 :     PyObject *init_args = PyTuple_Pack(2, self->msg, excs);
     863         [ -  + ]:        416 :     if (!init_args) {
     864                 :          0 :         return NULL;
     865                 :            :     }
     866                 :        416 :     PyObject *eg = PyObject_CallObject(
     867                 :            :         PyExc_BaseExceptionGroup, init_args);
     868                 :        416 :     Py_DECREF(init_args);
     869                 :        416 :     return eg;
     870                 :            : }
     871                 :            : 
     872                 :            : static int
     873                 :        603 : exceptiongroup_subset(
     874                 :            :     PyBaseExceptionGroupObject *_orig, PyObject *excs, PyObject **result)
     875                 :            : {
     876                 :            :     /* Sets *result to an ExceptionGroup wrapping excs with metadata from
     877                 :            :      * _orig. If excs is empty, sets *result to NULL.
     878                 :            :      * Returns 0 on success and -1 on error.
     879                 :            : 
     880                 :            :      * This function is used by split() to construct the match/rest parts,
     881                 :            :      * so excs is the matching or non-matching sub-sequence of orig->excs
     882                 :            :      * (this function does not verify that it is a subsequence).
     883                 :            :      */
     884                 :        603 :     PyObject *orig = (PyObject *)_orig;
     885                 :            : 
     886                 :        603 :     *result = NULL;
     887                 :        603 :     Py_ssize_t num_excs = PySequence_Size(excs);
     888         [ -  + ]:        603 :     if (num_excs < 0) {
     889                 :          0 :         return -1;
     890                 :            :     }
     891         [ +  + ]:        603 :     else if (num_excs == 0) {
     892                 :        161 :         return 0;
     893                 :            :     }
     894                 :            : 
     895                 :        442 :     PyObject *eg = PyObject_CallMethod(
     896                 :            :         orig, "derive", "(O)", excs);
     897         [ -  + ]:        442 :     if (!eg) {
     898                 :          0 :         return -1;
     899                 :            :     }
     900                 :            : 
     901         [ +  + ]:        442 :     if (!_PyBaseExceptionGroup_Check(eg)) {
     902                 :          2 :         PyErr_SetString(PyExc_TypeError,
     903                 :            :             "derive must return an instance of BaseExceptionGroup");
     904                 :          2 :         goto error;
     905                 :            :     }
     906                 :            : 
     907                 :            :     /* Now we hold a reference to the new eg */
     908                 :            : 
     909                 :        440 :     PyObject *tb = PyException_GetTraceback(orig);
     910         [ +  + ]:        440 :     if (tb) {
     911                 :        328 :         int res = PyException_SetTraceback(eg, tb);
     912                 :        328 :         Py_DECREF(tb);
     913         [ -  + ]:        328 :         if (res < 0) {
     914                 :          0 :             goto error;
     915                 :            :         }
     916                 :            :     }
     917                 :        440 :     PyException_SetContext(eg, PyException_GetContext(orig));
     918                 :        440 :     PyException_SetCause(eg, PyException_GetCause(orig));
     919                 :            : 
     920         [ +  + ]:        440 :     if (PyObject_HasAttr(orig, &_Py_ID(__notes__))) {
     921                 :         15 :         PyObject *notes = PyObject_GetAttr(orig, &_Py_ID(__notes__));
     922         [ -  + ]:         15 :         if (notes == NULL) {
     923                 :          0 :             goto error;
     924                 :            :         }
     925         [ +  + ]:         15 :         if (PySequence_Check(notes)) {
     926                 :            :             /* Make a copy so the parts have independent notes lists. */
     927                 :         13 :             PyObject *notes_copy = PySequence_List(notes);
     928                 :         13 :             Py_DECREF(notes);
     929         [ -  + ]:         13 :             if (notes_copy == NULL) {
     930                 :          0 :                 goto error;
     931                 :            :             }
     932                 :         13 :             int res = PyObject_SetAttr(eg, &_Py_ID(__notes__), notes_copy);
     933                 :         13 :             Py_DECREF(notes_copy);
     934         [ -  + ]:         13 :             if (res < 0) {
     935                 :          0 :                 goto error;
     936                 :            :             }
     937                 :            :         }
     938                 :            :         else {
     939                 :            :             /* __notes__ is supposed to be a list, and split() is not a
     940                 :            :              * good place to report earlier user errors, so we just ignore
     941                 :            :              * notes of non-sequence type.
     942                 :            :              */
     943                 :          2 :             Py_DECREF(notes);
     944                 :            :         }
     945                 :            :     }
     946                 :            : 
     947                 :        440 :     *result = eg;
     948                 :        440 :     return 0;
     949                 :          2 : error:
     950                 :          2 :     Py_DECREF(eg);
     951                 :          2 :     return -1;
     952                 :            : }
     953                 :            : 
     954                 :            : typedef enum {
     955                 :            :     /* Exception type or tuple of thereof */
     956                 :            :     EXCEPTION_GROUP_MATCH_BY_TYPE = 0,
     957                 :            :     /* A PyFunction returning True for matching exceptions */
     958                 :            :     EXCEPTION_GROUP_MATCH_BY_PREDICATE = 1,
     959                 :            :     /* A set of leaf exceptions to include in the result.
     960                 :            :      * This matcher type is used internally by the interpreter
     961                 :            :      * to construct reraised exceptions.
     962                 :            :      */
     963                 :            :     EXCEPTION_GROUP_MATCH_INSTANCES = 2
     964                 :            : } _exceptiongroup_split_matcher_type;
     965                 :            : 
     966                 :            : static int
     967                 :        186 : get_matcher_type(PyObject *value,
     968                 :            :                  _exceptiongroup_split_matcher_type *type)
     969                 :            : {
     970                 :            :     assert(value);
     971                 :            : 
     972         [ +  + ]:        186 :     if (PyFunction_Check(value)) {
     973                 :         10 :         *type = EXCEPTION_GROUP_MATCH_BY_PREDICATE;
     974                 :         10 :         return 0;
     975                 :            :     }
     976                 :            : 
     977   [ +  +  +  - ]:        176 :     if (PyExceptionClass_Check(value)) {
     978                 :        143 :         *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
     979                 :        143 :         return 0;
     980                 :            :     }
     981                 :            : 
     982         [ +  + ]:         33 :     if (PyTuple_CheckExact(value)) {
     983                 :         27 :         Py_ssize_t n = PyTuple_GET_SIZE(value);
     984         [ +  + ]:         79 :         for (Py_ssize_t i=0; i<n; i++) {
     985   [ +  +  -  + ]:         54 :             if (!PyExceptionClass_Check(PyTuple_GET_ITEM(value, i))) {
     986                 :          2 :                 goto error;
     987                 :            :             }
     988                 :            :         }
     989                 :         25 :         *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
     990                 :         25 :         return 0;
     991                 :            :     }
     992                 :            : 
     993                 :          6 : error:
     994                 :          8 :     PyErr_SetString(
     995                 :            :         PyExc_TypeError,
     996                 :            :         "expected a function, exception type or tuple of exception types");
     997                 :          8 :     return -1;
     998                 :            : }
     999                 :            : 
    1000                 :            : static int
    1001                 :       3023 : exceptiongroup_split_check_match(PyObject *exc,
    1002                 :            :                                  _exceptiongroup_split_matcher_type matcher_type,
    1003                 :            :                                  PyObject *matcher_value)
    1004                 :            : {
    1005   [ +  +  +  - ]:       3023 :     switch (matcher_type) {
    1006                 :       2596 :     case EXCEPTION_GROUP_MATCH_BY_TYPE: {
    1007                 :            :         assert(PyExceptionClass_Check(matcher_value) ||
    1008                 :            :                PyTuple_CheckExact(matcher_value));
    1009                 :       2596 :         return PyErr_GivenExceptionMatches(exc, matcher_value);
    1010                 :            :     }
    1011                 :         34 :     case EXCEPTION_GROUP_MATCH_BY_PREDICATE: {
    1012                 :            :         assert(PyFunction_Check(matcher_value));
    1013                 :         34 :         PyObject *exc_matches = PyObject_CallOneArg(matcher_value, exc);
    1014         [ -  + ]:         34 :         if (exc_matches == NULL) {
    1015                 :          0 :             return -1;
    1016                 :            :         }
    1017                 :         34 :         int is_true = PyObject_IsTrue(exc_matches);
    1018                 :         34 :         Py_DECREF(exc_matches);
    1019                 :         34 :         return is_true;
    1020                 :            :     }
    1021                 :        393 :     case EXCEPTION_GROUP_MATCH_INSTANCES: {
    1022                 :            :         assert(PySet_Check(matcher_value));
    1023         [ +  + ]:        393 :         if (!_PyBaseExceptionGroup_Check(exc)) {
    1024                 :        244 :             return PySet_Contains(matcher_value, exc);
    1025                 :            :         }
    1026                 :        149 :         return 0;
    1027                 :            :     }
    1028                 :            :     }
    1029                 :          0 :     return 0;
    1030                 :            : }
    1031                 :            : 
    1032                 :            : typedef struct {
    1033                 :            :     PyObject *match;
    1034                 :            :     PyObject *rest;
    1035                 :            : } _exceptiongroup_split_result;
    1036                 :            : 
    1037                 :            : static int
    1038                 :       3023 : exceptiongroup_split_recursive(PyObject *exc,
    1039                 :            :                                _exceptiongroup_split_matcher_type matcher_type,
    1040                 :            :                                PyObject *matcher_value,
    1041                 :            :                                bool construct_rest,
    1042                 :            :                                _exceptiongroup_split_result *result)
    1043                 :            : {
    1044                 :       3023 :     result->match = NULL;
    1045                 :       3023 :     result->rest = NULL;
    1046                 :            : 
    1047                 :       3023 :     int is_match = exceptiongroup_split_check_match(
    1048                 :            :         exc, matcher_type, matcher_value);
    1049         [ -  + ]:       3023 :     if (is_match < 0) {
    1050                 :          0 :         return -1;
    1051                 :            :     }
    1052                 :            : 
    1053         [ +  + ]:       3023 :     if (is_match) {
    1054                 :            :         /* Full match */
    1055                 :        334 :         result->match = Py_NewRef(exc);
    1056                 :        334 :         return 0;
    1057                 :            :     }
    1058         [ +  + ]:       2689 :     else if (!_PyBaseExceptionGroup_Check(exc)) {
    1059                 :            :         /* Leaf exception and no match */
    1060         [ +  + ]:        350 :         if (construct_rest) {
    1061                 :        155 :             result->rest = Py_NewRef(exc);
    1062                 :            :         }
    1063                 :        350 :         return 0;
    1064                 :            :     }
    1065                 :            : 
    1066                 :            :     /* Partial match */
    1067                 :            : 
    1068                 :       2339 :     PyBaseExceptionGroupObject *eg = _PyBaseExceptionGroupObject_cast(exc);
    1069                 :            :     assert(PyTuple_CheckExact(eg->excs));
    1070                 :       2339 :     Py_ssize_t num_excs = PyTuple_Size(eg->excs);
    1071         [ -  + ]:       2339 :     if (num_excs < 0) {
    1072                 :          0 :         return -1;
    1073                 :            :     }
    1074                 :            :     assert(num_excs > 0); /* checked in constructor, and excs is read-only */
    1075                 :            : 
    1076                 :       2339 :     int retval = -1;
    1077                 :       2339 :     PyObject *match_list = PyList_New(0);
    1078         [ -  + ]:       2339 :     if (!match_list) {
    1079                 :          0 :         return -1;
    1080                 :            :     }
    1081                 :            : 
    1082                 :       2339 :     PyObject *rest_list = NULL;
    1083         [ +  + ]:       2339 :     if (construct_rest) {
    1084                 :       1172 :         rest_list = PyList_New(0);
    1085         [ -  + ]:       1172 :         if (!rest_list) {
    1086                 :          0 :             goto done;
    1087                 :            :         }
    1088                 :            :     }
    1089                 :            :     /* recursive calls */
    1090         [ +  + ]:       3148 :     for (Py_ssize_t i = 0; i < num_excs; i++) {
    1091                 :       2747 :         PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
    1092                 :            :         _exceptiongroup_split_result rec_result;
    1093         [ +  + ]:       2747 :         if (_Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) {
    1094                 :       1938 :             goto done;
    1095                 :            :         }
    1096         [ +  + ]:       2745 :         if (exceptiongroup_split_recursive(
    1097                 :            :                 e, matcher_type, matcher_value,
    1098                 :            :                 construct_rest, &rec_result) < 0) {
    1099                 :            :             assert(!rec_result.match);
    1100                 :            :             assert(!rec_result.rest);
    1101                 :       1936 :             _Py_LeaveRecursiveCall();
    1102                 :       1936 :             goto done;
    1103                 :            :         }
    1104                 :        809 :         _Py_LeaveRecursiveCall();
    1105         [ +  + ]:        809 :         if (rec_result.match) {
    1106                 :            :             assert(PyList_CheckExact(match_list));
    1107         [ -  + ]:        420 :             if (PyList_Append(match_list, rec_result.match) < 0) {
    1108                 :          0 :                 Py_DECREF(rec_result.match);
    1109                 :          0 :                 goto done;
    1110                 :            :             }
    1111                 :        420 :             Py_DECREF(rec_result.match);
    1112                 :            :         }
    1113         [ +  + ]:        809 :         if (rec_result.rest) {
    1114                 :            :             assert(construct_rest);
    1115                 :            :             assert(PyList_CheckExact(rest_list));
    1116         [ -  + ]:        205 :             if (PyList_Append(rest_list, rec_result.rest) < 0) {
    1117                 :          0 :                 Py_DECREF(rec_result.rest);
    1118                 :          0 :                 goto done;
    1119                 :            :             }
    1120                 :        205 :             Py_DECREF(rec_result.rest);
    1121                 :            :         }
    1122                 :            :     }
    1123                 :            : 
    1124                 :            :     /* construct result */
    1125         [ +  + ]:        401 :     if (exceptiongroup_subset(eg, match_list, &result->match) < 0) {
    1126                 :          2 :         goto done;
    1127                 :            :     }
    1128                 :            : 
    1129         [ +  + ]:        399 :     if (construct_rest) {
    1130                 :            :         assert(PyList_CheckExact(rest_list));
    1131         [ -  + ]:        202 :         if (exceptiongroup_subset(eg, rest_list, &result->rest) < 0) {
    1132         [ #  # ]:          0 :             Py_CLEAR(result->match);
    1133                 :          0 :             goto done;
    1134                 :            :         }
    1135                 :            :     }
    1136                 :        399 :     retval = 0;
    1137                 :       2339 : done:
    1138                 :       2339 :     Py_DECREF(match_list);
    1139                 :       2339 :     Py_XDECREF(rest_list);
    1140         [ +  + ]:       2339 :     if (retval < 0) {
    1141         [ -  + ]:       1940 :         Py_CLEAR(result->match);
    1142         [ -  + ]:       1940 :         Py_CLEAR(result->rest);
    1143                 :            :     }
    1144                 :       2339 :     return retval;
    1145                 :            : }
    1146                 :            : 
    1147                 :            : static PyObject *
    1148                 :        146 : BaseExceptionGroup_split(PyObject *self, PyObject *args)
    1149                 :            : {
    1150                 :        146 :     PyObject *matcher_value = NULL;
    1151         [ -  + ]:        146 :     if (!PyArg_UnpackTuple(args, "split", 1, 1, &matcher_value)) {
    1152                 :          0 :         return NULL;
    1153                 :            :     }
    1154                 :            : 
    1155                 :            :     _exceptiongroup_split_matcher_type matcher_type;
    1156         [ +  + ]:        146 :     if (get_matcher_type(matcher_value, &matcher_type) < 0) {
    1157                 :          4 :         return NULL;
    1158                 :            :     }
    1159                 :            : 
    1160                 :            :     _exceptiongroup_split_result split_result;
    1161                 :        142 :     bool construct_rest = true;
    1162         [ +  + ]:        142 :     if (exceptiongroup_split_recursive(
    1163                 :            :             self, matcher_type, matcher_value,
    1164                 :            :             construct_rest, &split_result) < 0) {
    1165                 :          2 :         return NULL;
    1166                 :            :     }
    1167                 :            : 
    1168                 :        280 :     PyObject *result = PyTuple_Pack(
    1169                 :            :             2,
    1170         [ +  + ]:        140 :             split_result.match ? split_result.match : Py_None,
    1171         [ +  + ]:        140 :             split_result.rest ? split_result.rest : Py_None);
    1172                 :            : 
    1173                 :        140 :     Py_XDECREF(split_result.match);
    1174                 :        140 :     Py_XDECREF(split_result.rest);
    1175                 :        140 :     return result;
    1176                 :            : }
    1177                 :            : 
    1178                 :            : static PyObject *
    1179                 :         40 : BaseExceptionGroup_subgroup(PyObject *self, PyObject *args)
    1180                 :            : {
    1181                 :         40 :     PyObject *matcher_value = NULL;
    1182         [ -  + ]:         40 :     if (!PyArg_UnpackTuple(args, "subgroup", 1, 1, &matcher_value)) {
    1183                 :          0 :         return NULL;
    1184                 :            :     }
    1185                 :            : 
    1186                 :            :     _exceptiongroup_split_matcher_type matcher_type;
    1187         [ +  + ]:         40 :     if (get_matcher_type(matcher_value, &matcher_type) < 0) {
    1188                 :          4 :         return NULL;
    1189                 :            :     }
    1190                 :            : 
    1191                 :            :     _exceptiongroup_split_result split_result;
    1192                 :         36 :     bool construct_rest = false;
    1193         [ +  + ]:         36 :     if (exceptiongroup_split_recursive(
    1194                 :            :             self, matcher_type, matcher_value,
    1195                 :            :             construct_rest, &split_result) < 0) {
    1196                 :          2 :         return NULL;
    1197                 :            :     }
    1198                 :            : 
    1199         [ +  + ]:         34 :     PyObject *result = Py_NewRef(
    1200                 :            :             split_result.match ? split_result.match : Py_None);
    1201                 :            : 
    1202                 :         34 :     Py_XDECREF(split_result.match);
    1203                 :            :     assert(!split_result.rest);
    1204                 :         34 :     return result;
    1205                 :            : }
    1206                 :            : 
    1207                 :            : static int
    1208                 :        195 : collect_exception_group_leaves(PyObject *exc, PyObject *leaves)
    1209                 :            : {
    1210         [ -  + ]:        195 :     if (Py_IsNone(exc)) {
    1211                 :          0 :         return 0;
    1212                 :            :     }
    1213                 :            : 
    1214                 :            :     assert(PyExceptionInstance_Check(exc));
    1215                 :            :     assert(PySet_Check(leaves));
    1216                 :            : 
    1217                 :            :     /* Add all leaf exceptions in exc to the leaves set */
    1218                 :            : 
    1219         [ +  + ]:        195 :     if (!_PyBaseExceptionGroup_Check(exc)) {
    1220         [ -  + ]:         94 :         if (PySet_Add(leaves, exc) < 0) {
    1221                 :          0 :             return -1;
    1222                 :            :         }
    1223                 :         94 :         return 0;
    1224                 :            :     }
    1225                 :        101 :     PyBaseExceptionGroupObject *eg = _PyBaseExceptionGroupObject_cast(exc);
    1226                 :        101 :     Py_ssize_t num_excs = PyTuple_GET_SIZE(eg->excs);
    1227                 :            :     /* recursive calls */
    1228         [ +  + ]:        232 :     for (Py_ssize_t i = 0; i < num_excs; i++) {
    1229                 :        131 :         PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
    1230         [ -  + ]:        131 :         if (_Py_EnterRecursiveCall(" in collect_exception_group_leaves")) {
    1231                 :          0 :             return -1;
    1232                 :            :         }
    1233                 :        131 :         int res = collect_exception_group_leaves(e, leaves);
    1234                 :        131 :         _Py_LeaveRecursiveCall();
    1235         [ -  + ]:        131 :         if (res < 0) {
    1236                 :          0 :             return -1;
    1237                 :            :         }
    1238                 :            :     }
    1239                 :        101 :     return 0;
    1240                 :            : }
    1241                 :            : 
    1242                 :            : /* This function is used by the interpreter to construct reraised
    1243                 :            :  * exception groups. It takes an exception group eg and a list
    1244                 :            :  * of exception groups keep and returns the sub-exception group
    1245                 :            :  * of eg which contains all leaf exceptions that are contained
    1246                 :            :  * in any exception group in keep.
    1247                 :            :  */
    1248                 :            : static PyObject *
    1249                 :        100 : exception_group_projection(PyObject *eg, PyObject *keep)
    1250                 :            : {
    1251                 :            :     assert(_PyBaseExceptionGroup_Check(eg));
    1252                 :            :     assert(PyList_CheckExact(keep));
    1253                 :            : 
    1254                 :        100 :     PyObject *leaves = PySet_New(NULL);
    1255         [ -  + ]:        100 :     if (!leaves) {
    1256                 :          0 :         return NULL;
    1257                 :            :     }
    1258                 :            : 
    1259                 :        100 :     Py_ssize_t n = PyList_GET_SIZE(keep);
    1260         [ +  + ]:        164 :     for (Py_ssize_t i = 0; i < n; i++) {
    1261                 :         64 :         PyObject *e = PyList_GET_ITEM(keep, i);
    1262                 :            :         assert(e != NULL);
    1263                 :            :         assert(_PyBaseExceptionGroup_Check(e));
    1264         [ -  + ]:         64 :         if (collect_exception_group_leaves(e, leaves) < 0) {
    1265                 :          0 :             Py_DECREF(leaves);
    1266                 :          0 :             return NULL;
    1267                 :            :         }
    1268                 :            :     }
    1269                 :            : 
    1270                 :            :     _exceptiongroup_split_result split_result;
    1271                 :        100 :     bool construct_rest = false;
    1272                 :        100 :     int err = exceptiongroup_split_recursive(
    1273                 :            :                 eg, EXCEPTION_GROUP_MATCH_INSTANCES, leaves,
    1274                 :            :                 construct_rest, &split_result);
    1275                 :        100 :     Py_DECREF(leaves);
    1276         [ -  + ]:        100 :     if (err < 0) {
    1277                 :          0 :         return NULL;
    1278                 :            :     }
    1279                 :            : 
    1280                 :        200 :     PyObject *result = split_result.match ?
    1281         [ +  + ]:        100 :         split_result.match : Py_NewRef(Py_None);
    1282                 :            :     assert(split_result.rest == NULL);
    1283                 :        100 :     return result;
    1284                 :            : }
    1285                 :            : 
    1286                 :            : static bool
    1287                 :         80 : is_same_exception_metadata(PyObject *exc1, PyObject *exc2)
    1288                 :            : {
    1289                 :            :     assert(PyExceptionInstance_Check(exc1));
    1290                 :            :     assert(PyExceptionInstance_Check(exc2));
    1291                 :            : 
    1292                 :         80 :     PyBaseExceptionObject *e1 = (PyBaseExceptionObject *)exc1;
    1293                 :         80 :     PyBaseExceptionObject *e2 = (PyBaseExceptionObject *)exc2;
    1294                 :            : 
    1295                 :        160 :     return (e1->notes == e2->notes &&
    1296         [ +  + ]:         80 :             e1->traceback == e2->traceback &&
    1297   [ +  -  +  - ]:        224 :             e1->cause == e2->cause &&
    1298         [ +  - ]:         64 :             e1->context == e2->context);
    1299                 :            : }
    1300                 :            : 
    1301                 :            : /*
    1302                 :            :    This function is used by the interpreter to calculate
    1303                 :            :    the exception group to be raised at the end of a
    1304                 :            :    try-except* construct.
    1305                 :            : 
    1306                 :            :    orig: the original except that was caught.
    1307                 :            :    excs: a list of exceptions that were raised/reraised
    1308                 :            :          in the except* clauses.
    1309                 :            : 
    1310                 :            :    Calculates an exception group to raise. It contains
    1311                 :            :    all exceptions in excs, where those that were reraised
    1312                 :            :    have same nesting structure as in orig, and those that
    1313                 :            :    were raised (if any) are added as siblings in a new EG.
    1314                 :            : 
    1315                 :            :    Returns NULL and sets an exception on failure.
    1316                 :            : */
    1317                 :            : PyObject *
    1318                 :        150 : _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
    1319                 :            : {
    1320                 :            :     assert(PyExceptionInstance_Check(orig));
    1321                 :            :     assert(PyList_Check(excs));
    1322                 :            : 
    1323                 :        150 :     Py_ssize_t numexcs = PyList_GET_SIZE(excs);
    1324                 :            : 
    1325         [ -  + ]:        150 :     if (numexcs == 0) {
    1326                 :          0 :         return Py_NewRef(Py_None);
    1327                 :            :     }
    1328                 :            : 
    1329         [ +  + ]:        150 :     if (!_PyBaseExceptionGroup_Check(orig)) {
    1330                 :            :         /* a naked exception was caught and wrapped. Only one except* clause
    1331                 :            :          * could have executed,so there is at most one exception to raise.
    1332                 :            :          */
    1333                 :            : 
    1334                 :            :         assert(numexcs == 1 || (numexcs == 2 && PyList_GET_ITEM(excs, 1) == Py_None));
    1335                 :            : 
    1336                 :         50 :         PyObject *e = PyList_GET_ITEM(excs, 0);
    1337                 :            :         assert(e != NULL);
    1338                 :         50 :         return Py_NewRef(e);
    1339                 :            :     }
    1340                 :            : 
    1341                 :        100 :     PyObject *raised_list = PyList_New(0);
    1342         [ -  + ]:        100 :     if (raised_list == NULL) {
    1343                 :          0 :         return NULL;
    1344                 :            :     }
    1345                 :        100 :     PyObject* reraised_list = PyList_New(0);
    1346         [ -  + ]:        100 :     if (reraised_list == NULL) {
    1347                 :          0 :         Py_DECREF(raised_list);
    1348                 :          0 :         return NULL;
    1349                 :            :     }
    1350                 :            : 
    1351                 :            :     /* Now we are holding refs to raised_list and reraised_list */
    1352                 :            : 
    1353                 :        100 :     PyObject *result = NULL;
    1354                 :            : 
    1355                 :            :     /* Split excs into raised and reraised by comparing metadata with orig */
    1356         [ +  + ]:        228 :     for (Py_ssize_t i = 0; i < numexcs; i++) {
    1357                 :        128 :         PyObject *e = PyList_GET_ITEM(excs, i);
    1358                 :            :         assert(e != NULL);
    1359         [ +  + ]:        128 :         if (Py_IsNone(e)) {
    1360                 :         48 :             continue;
    1361                 :            :         }
    1362                 :         80 :         bool is_reraise = is_same_exception_metadata(e, orig);
    1363         [ +  + ]:         80 :         PyObject *append_list = is_reraise ? reraised_list : raised_list;
    1364         [ -  + ]:         80 :         if (PyList_Append(append_list, e) < 0) {
    1365                 :          0 :             goto done;
    1366                 :            :         }
    1367                 :            :     }
    1368                 :            : 
    1369                 :        100 :     PyObject *reraised_eg = exception_group_projection(orig, reraised_list);
    1370         [ -  + ]:        100 :     if (reraised_eg == NULL) {
    1371                 :          0 :         goto done;
    1372                 :            :     }
    1373                 :            : 
    1374                 :            :     if (!Py_IsNone(reraised_eg)) {
    1375                 :            :         assert(is_same_exception_metadata(reraised_eg, orig));
    1376                 :            :     }
    1377                 :        100 :     Py_ssize_t num_raised = PyList_GET_SIZE(raised_list);
    1378         [ +  + ]:        100 :     if (num_raised == 0) {
    1379                 :         88 :         result = reraised_eg;
    1380                 :            :     }
    1381         [ -  + ]:         12 :     else if (num_raised > 0) {
    1382                 :         12 :         int res = 0;
    1383         [ +  + ]:         12 :         if (!Py_IsNone(reraised_eg)) {
    1384                 :          4 :             res = PyList_Append(raised_list, reraised_eg);
    1385                 :            :         }
    1386                 :         12 :         Py_DECREF(reraised_eg);
    1387         [ -  + ]:         12 :         if (res < 0) {
    1388                 :          0 :             goto done;
    1389                 :            :         }
    1390                 :         12 :         result = _PyExc_CreateExceptionGroup("", raised_list);
    1391         [ +  - ]:         12 :         if (result == NULL) {
    1392                 :          0 :             goto done;
    1393                 :            :         }
    1394                 :            :     }
    1395                 :            : 
    1396                 :         12 : done:
    1397                 :        100 :     Py_XDECREF(raised_list);
    1398                 :        100 :     Py_XDECREF(reraised_list);
    1399                 :        100 :     return result;
    1400                 :            : }
    1401                 :            : 
    1402                 :            : static PyMemberDef BaseExceptionGroup_members[] = {
    1403                 :            :     {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY,
    1404                 :            :         PyDoc_STR("exception message")},
    1405                 :            :     {"exceptions", T_OBJECT, offsetof(PyBaseExceptionGroupObject, excs), READONLY,
    1406                 :            :         PyDoc_STR("nested exceptions")},
    1407                 :            :     {NULL}  /* Sentinel */
    1408                 :            : };
    1409                 :            : 
    1410                 :            : static PyMethodDef BaseExceptionGroup_methods[] = {
    1411                 :            :     {"__class_getitem__", (PyCFunction)Py_GenericAlias,
    1412                 :            :       METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
    1413                 :            :     {"derive", (PyCFunction)BaseExceptionGroup_derive, METH_VARARGS},
    1414                 :            :     {"split", (PyCFunction)BaseExceptionGroup_split, METH_VARARGS},
    1415                 :            :     {"subgroup", (PyCFunction)BaseExceptionGroup_subgroup, METH_VARARGS},
    1416                 :            :     {NULL}
    1417                 :            : };
    1418                 :            : 
    1419                 :            : ComplexExtendsException(PyExc_BaseException, BaseExceptionGroup,
    1420                 :            :     BaseExceptionGroup, BaseExceptionGroup_new /* new */,
    1421                 :            :     BaseExceptionGroup_methods, BaseExceptionGroup_members,
    1422                 :            :     0 /* getset */, BaseExceptionGroup_str,
    1423                 :            :     "A combination of multiple unrelated exceptions.");
    1424                 :            : 
    1425                 :            : /*
    1426                 :            :  *    ExceptionGroup extends BaseExceptionGroup, Exception
    1427                 :            :  */
    1428                 :            : static PyObject*
    1429                 :       3138 : create_exception_group_class(void) {
    1430                 :       3138 :     struct _Py_exc_state *state = get_exc_state();
    1431                 :            : 
    1432                 :       3138 :     PyObject *bases = PyTuple_Pack(
    1433                 :            :         2, PyExc_BaseExceptionGroup, PyExc_Exception);
    1434         [ -  + ]:       3138 :     if (bases == NULL) {
    1435                 :          0 :         return NULL;
    1436                 :            :     }
    1437                 :            : 
    1438                 :            :     assert(!state->PyExc_ExceptionGroup);
    1439                 :       3138 :     state->PyExc_ExceptionGroup = PyErr_NewException(
    1440                 :            :         "builtins.ExceptionGroup", bases, NULL);
    1441                 :            : 
    1442                 :       3138 :     Py_DECREF(bases);
    1443                 :       3138 :     return state->PyExc_ExceptionGroup;
    1444                 :            : }
    1445                 :            : 
    1446                 :            : /*
    1447                 :            :  *    KeyboardInterrupt extends BaseException
    1448                 :            :  */
    1449                 :            : SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
    1450                 :            :                        "Program interrupted by user.");
    1451                 :            : 
    1452                 :            : 
    1453                 :            : /*
    1454                 :            :  *    ImportError extends Exception
    1455                 :            :  */
    1456                 :            : 
    1457                 :            : static int
    1458                 :      55829 : ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds)
    1459                 :            : {
    1460                 :            :     static char *kwlist[] = {"name", "path", 0};
    1461                 :            :     PyObject *empty_tuple;
    1462                 :      55829 :     PyObject *msg = NULL;
    1463                 :      55829 :     PyObject *name = NULL;
    1464                 :      55829 :     PyObject *path = NULL;
    1465                 :            : 
    1466         [ -  + ]:      55829 :     if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1)
    1467                 :          0 :         return -1;
    1468                 :            : 
    1469                 :      55829 :     empty_tuple = PyTuple_New(0);
    1470         [ -  + ]:      55829 :     if (!empty_tuple)
    1471                 :          0 :         return -1;
    1472         [ +  + ]:      55829 :     if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist,
    1473                 :            :                                      &name, &path)) {
    1474                 :          6 :         Py_DECREF(empty_tuple);
    1475                 :          6 :         return -1;
    1476                 :            :     }
    1477                 :      55823 :     Py_DECREF(empty_tuple);
    1478                 :            : 
    1479                 :      55823 :     Py_XINCREF(name);
    1480                 :      55823 :     Py_XSETREF(self->name, name);
    1481                 :            : 
    1482                 :      55823 :     Py_XINCREF(path);
    1483                 :      55823 :     Py_XSETREF(self->path, path);
    1484                 :            : 
    1485         [ +  + ]:      55823 :     if (PyTuple_GET_SIZE(args) == 1) {
    1486                 :      55760 :         msg = PyTuple_GET_ITEM(args, 0);
    1487                 :      55760 :         Py_INCREF(msg);
    1488                 :            :     }
    1489                 :      55823 :     Py_XSETREF(self->msg, msg);
    1490                 :            : 
    1491                 :      55823 :     return 0;
    1492                 :            : }
    1493                 :            : 
    1494                 :            : static int
    1495                 :      55881 : ImportError_clear(PyImportErrorObject *self)
    1496                 :            : {
    1497         [ +  + ]:      55881 :     Py_CLEAR(self->msg);
    1498         [ +  + ]:      55881 :     Py_CLEAR(self->name);
    1499         [ +  + ]:      55881 :     Py_CLEAR(self->path);
    1500                 :      55881 :     return BaseException_clear((PyBaseExceptionObject *)self);
    1501                 :            : }
    1502                 :            : 
    1503                 :            : static void
    1504                 :      55828 : ImportError_dealloc(PyImportErrorObject *self)
    1505                 :            : {
    1506                 :      55828 :     _PyObject_GC_UNTRACK(self);
    1507                 :      55828 :     ImportError_clear(self);
    1508                 :      55828 :     Py_TYPE(self)->tp_free((PyObject *)self);
    1509                 :      55828 : }
    1510                 :            : 
    1511                 :            : static int
    1512                 :        390 : ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg)
    1513                 :            : {
    1514   [ +  -  -  + ]:        390 :     Py_VISIT(self->msg);
    1515   [ +  +  -  + ]:        390 :     Py_VISIT(self->name);
    1516   [ +  +  -  + ]:        390 :     Py_VISIT(self->path);
    1517                 :        390 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
    1518                 :            : }
    1519                 :            : 
    1520                 :            : static PyObject *
    1521                 :        110 : ImportError_str(PyImportErrorObject *self)
    1522                 :            : {
    1523   [ +  -  +  + ]:        110 :     if (self->msg && PyUnicode_CheckExact(self->msg)) {
    1524                 :        106 :         Py_INCREF(self->msg);
    1525                 :        106 :         return self->msg;
    1526                 :            :     }
    1527                 :            :     else {
    1528                 :          4 :         return BaseException_str((PyBaseExceptionObject *)self);
    1529                 :            :     }
    1530                 :            : }
    1531                 :            : 
    1532                 :            : static PyObject *
    1533                 :         38 : ImportError_getstate(PyImportErrorObject *self)
    1534                 :            : {
    1535                 :         38 :     PyObject *dict = ((PyBaseExceptionObject *)self)->dict;
    1536   [ +  +  +  + ]:         38 :     if (self->name || self->path) {
    1537         [ -  + ]:         24 :         dict = dict ? PyDict_Copy(dict) : PyDict_New();
    1538         [ -  + ]:         24 :         if (dict == NULL)
    1539                 :          0 :             return NULL;
    1540   [ +  +  -  + ]:         24 :         if (self->name && PyDict_SetItem(dict, &_Py_ID(name), self->name) < 0) {
    1541                 :          0 :             Py_DECREF(dict);
    1542                 :          0 :             return NULL;
    1543                 :            :         }
    1544   [ +  +  -  + ]:         24 :         if (self->path && PyDict_SetItem(dict, &_Py_ID(path), self->path) < 0) {
    1545                 :          0 :             Py_DECREF(dict);
    1546                 :          0 :             return NULL;
    1547                 :            :         }
    1548                 :         24 :         return dict;
    1549                 :            :     }
    1550         [ -  + ]:         14 :     else if (dict) {
    1551                 :          0 :         Py_INCREF(dict);
    1552                 :          0 :         return dict;
    1553                 :            :     }
    1554                 :            :     else {
    1555                 :         14 :         Py_RETURN_NONE;
    1556                 :            :     }
    1557                 :            : }
    1558                 :            : 
    1559                 :            : /* Pickling support */
    1560                 :            : static PyObject *
    1561                 :         38 : ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored))
    1562                 :            : {
    1563                 :            :     PyObject *res;
    1564                 :            :     PyObject *args;
    1565                 :         38 :     PyObject *state = ImportError_getstate(self);
    1566         [ -  + ]:         38 :     if (state == NULL)
    1567                 :          0 :         return NULL;
    1568                 :         38 :     args = ((PyBaseExceptionObject *)self)->args;
    1569         [ +  + ]:         38 :     if (state == Py_None)
    1570                 :         14 :         res = PyTuple_Pack(2, Py_TYPE(self), args);
    1571                 :            :     else
    1572                 :         24 :         res = PyTuple_Pack(3, Py_TYPE(self), args, state);
    1573                 :         38 :     Py_DECREF(state);
    1574                 :         38 :     return res;
    1575                 :            : }
    1576                 :            : 
    1577                 :            : static PyMemberDef ImportError_members[] = {
    1578                 :            :     {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0,
    1579                 :            :         PyDoc_STR("exception message")},
    1580                 :            :     {"name", T_OBJECT, offsetof(PyImportErrorObject, name), 0,
    1581                 :            :         PyDoc_STR("module name")},
    1582                 :            :     {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0,
    1583                 :            :         PyDoc_STR("module path")},
    1584                 :            :     {NULL}  /* Sentinel */
    1585                 :            : };
    1586                 :            : 
    1587                 :            : static PyMethodDef ImportError_methods[] = {
    1588                 :            :     {"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS},
    1589                 :            :     {NULL}
    1590                 :            : };
    1591                 :            : 
    1592                 :            : ComplexExtendsException(PyExc_Exception, ImportError,
    1593                 :            :                         ImportError, 0 /* new */,
    1594                 :            :                         ImportError_methods, ImportError_members,
    1595                 :            :                         0 /* getset */, ImportError_str,
    1596                 :            :                         "Import can't find module, or can't find name in "
    1597                 :            :                         "module.");
    1598                 :            : 
    1599                 :            : /*
    1600                 :            :  *    ModuleNotFoundError extends ImportError
    1601                 :            :  */
    1602                 :            : 
    1603                 :            : MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
    1604                 :            :                          "Module not found.");
    1605                 :            : 
    1606                 :            : /*
    1607                 :            :  *    OSError extends Exception
    1608                 :            :  */
    1609                 :            : 
    1610                 :            : #ifdef MS_WINDOWS
    1611                 :            : #include "errmap.h"
    1612                 :            : #endif
    1613                 :            : 
    1614                 :            : /* Where a function has a single filename, such as open() or some
    1615                 :            :  * of the os module functions, PyErr_SetFromErrnoWithFilename() is
    1616                 :            :  * called, giving a third argument which is the filename.  But, so
    1617                 :            :  * that old code using in-place unpacking doesn't break, e.g.:
    1618                 :            :  *
    1619                 :            :  * except OSError, (errno, strerror):
    1620                 :            :  *
    1621                 :            :  * we hack args so that it only contains two items.  This also
    1622                 :            :  * means we need our own __str__() which prints out the filename
    1623                 :            :  * when it was supplied.
    1624                 :            :  *
    1625                 :            :  * (If a function has two filenames, such as rename(), symlink(),
    1626                 :            :  * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
    1627                 :            :  * which allows passing in a second filename.)
    1628                 :            :  */
    1629                 :            : 
    1630                 :            : /* This function doesn't cleanup on error, the caller should */
    1631                 :            : static int
    1632                 :     363755 : oserror_parse_args(PyObject **p_args,
    1633                 :            :                    PyObject **myerrno, PyObject **strerror,
    1634                 :            :                    PyObject **filename, PyObject **filename2
    1635                 :            : #ifdef MS_WINDOWS
    1636                 :            :                    , PyObject **winerror
    1637                 :            : #endif
    1638                 :            :                   )
    1639                 :            : {
    1640                 :            :     Py_ssize_t nargs;
    1641                 :     363755 :     PyObject *args = *p_args;
    1642                 :            : #ifndef MS_WINDOWS
    1643                 :            :     /*
    1644                 :            :      * ignored on non-Windows platforms,
    1645                 :            :      * but parsed so OSError has a consistent signature
    1646                 :            :      */
    1647                 :     363755 :     PyObject *_winerror = NULL;
    1648                 :     363755 :     PyObject **winerror = &_winerror;
    1649                 :            : #endif /* MS_WINDOWS */
    1650                 :            : 
    1651                 :     363755 :     nargs = PyTuple_GET_SIZE(args);
    1652                 :            : 
    1653   [ +  +  +  - ]:     363755 :     if (nargs >= 2 && nargs <= 5) {
    1654         [ -  + ]:     361457 :         if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
    1655                 :            :                                myerrno, strerror,
    1656                 :            :                                filename, winerror, filename2))
    1657                 :          0 :             return -1;
    1658                 :            : #ifdef MS_WINDOWS
    1659                 :            :         if (*winerror && PyLong_Check(*winerror)) {
    1660                 :            :             long errcode, winerrcode;
    1661                 :            :             PyObject *newargs;
    1662                 :            :             Py_ssize_t i;
    1663                 :            : 
    1664                 :            :             winerrcode = PyLong_AsLong(*winerror);
    1665                 :            :             if (winerrcode == -1 && PyErr_Occurred())
    1666                 :            :                 return -1;
    1667                 :            :             errcode = winerror_to_errno(winerrcode);
    1668                 :            :             *myerrno = PyLong_FromLong(errcode);
    1669                 :            :             if (!*myerrno)
    1670                 :            :                 return -1;
    1671                 :            :             newargs = PyTuple_New(nargs);
    1672                 :            :             if (!newargs)
    1673                 :            :                 return -1;
    1674                 :            :             PyTuple_SET_ITEM(newargs, 0, *myerrno);
    1675                 :            :             for (i = 1; i < nargs; i++) {
    1676                 :            :                 PyObject *val = PyTuple_GET_ITEM(args, i);
    1677                 :            :                 Py_INCREF(val);
    1678                 :            :                 PyTuple_SET_ITEM(newargs, i, val);
    1679                 :            :             }
    1680                 :            :             Py_DECREF(args);
    1681                 :            :             args = *p_args = newargs;
    1682                 :            :         }
    1683                 :            : #endif /* MS_WINDOWS */
    1684                 :            :     }
    1685                 :            : 
    1686                 :     363755 :     return 0;
    1687                 :            : }
    1688                 :            : 
    1689                 :            : static int
    1690                 :     363755 : oserror_init(PyOSErrorObject *self, PyObject **p_args,
    1691                 :            :              PyObject *myerrno, PyObject *strerror,
    1692                 :            :              PyObject *filename, PyObject *filename2
    1693                 :            : #ifdef MS_WINDOWS
    1694                 :            :              , PyObject *winerror
    1695                 :            : #endif
    1696                 :            :              )
    1697                 :            : {
    1698                 :     363755 :     PyObject *args = *p_args;
    1699                 :     363755 :     Py_ssize_t nargs = PyTuple_GET_SIZE(args);
    1700                 :            : 
    1701                 :            :     /* self->filename will remain Py_None otherwise */
    1702   [ +  +  +  + ]:     363755 :     if (filename && filename != Py_None) {
    1703   [ +  +  +  + ]:     294079 :         if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
    1704                 :         35 :             PyNumber_Check(filename)) {
    1705                 :            :             /* BlockingIOError's 3rd argument can be the number of
    1706                 :            :              * characters written.
    1707                 :            :              */
    1708                 :         32 :             self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
    1709   [ -  +  -  - ]:         32 :             if (self->written == -1 && PyErr_Occurred())
    1710                 :          0 :                 return -1;
    1711                 :            :         }
    1712                 :            :         else {
    1713                 :     294012 :             Py_INCREF(filename);
    1714                 :     294012 :             self->filename = filename;
    1715                 :            : 
    1716   [ +  +  +  - ]:     294012 :             if (filename2 && filename2 != Py_None) {
    1717                 :        135 :                 Py_INCREF(filename2);
    1718                 :        135 :                 self->filename2 = filename2;
    1719                 :            :             }
    1720                 :            : 
    1721   [ +  -  +  - ]:     294012 :             if (nargs >= 2 && nargs <= 5) {
    1722                 :            :                 /* filename, filename2, and winerror are removed from the args tuple
    1723                 :            :                    (for compatibility purposes, see test_exceptions.py) */
    1724                 :     294012 :                 PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
    1725         [ -  + ]:     294012 :                 if (!subslice)
    1726                 :          0 :                     return -1;
    1727                 :            : 
    1728                 :     294012 :                 Py_DECREF(args);  /* replacing args */
    1729                 :     294012 :                 *p_args = args = subslice;
    1730                 :            :             }
    1731                 :            :         }
    1732                 :            :     }
    1733                 :     363755 :     Py_XINCREF(myerrno);
    1734                 :     363755 :     self->myerrno = myerrno;
    1735                 :            : 
    1736                 :     363755 :     Py_XINCREF(strerror);
    1737                 :     363755 :     self->strerror = strerror;
    1738                 :            : 
    1739                 :            : #ifdef MS_WINDOWS
    1740                 :            :     Py_XINCREF(winerror);
    1741                 :            :     self->winerror = winerror;
    1742                 :            : #endif
    1743                 :            : 
    1744                 :            :     /* Steals the reference to args */
    1745                 :     363755 :     Py_XSETREF(self->args, args);
    1746                 :     363755 :     *p_args = args = NULL;
    1747                 :            : 
    1748                 :     363755 :     return 0;
    1749                 :            : }
    1750                 :            : 
    1751                 :            : static PyObject *
    1752                 :            : OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
    1753                 :            : static int
    1754                 :            : OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds);
    1755                 :            : 
    1756                 :            : static int
    1757                 :    1091409 : oserror_use_init(PyTypeObject *type)
    1758                 :            : {
    1759                 :            :     /* When __init__ is defined in an OSError subclass, we want any
    1760                 :            :        extraneous argument to __new__ to be ignored.  The only reasonable
    1761                 :            :        solution, given __new__ takes a variable number of arguments,
    1762                 :            :        is to defer arg parsing and initialization to __init__.
    1763                 :            : 
    1764                 :            :        But when __new__ is overridden as well, it should call our __new__
    1765                 :            :        with the right arguments.
    1766                 :            : 
    1767                 :            :        (see http://bugs.python.org/issue12555#msg148829 )
    1768                 :            :     */
    1769         [ +  + ]:    1091409 :     if (type->tp_init != (initproc) OSError_init &&
    1770         [ +  + ]:        171 :         type->tp_new == (newfunc) OSError_new) {
    1771                 :            :         assert((PyObject *) type != PyExc_OSError);
    1772                 :        165 :         return 1;
    1773                 :            :     }
    1774                 :    1091244 :     return 0;
    1775                 :            : }
    1776                 :            : 
    1777                 :            : static PyObject *
    1778                 :     363827 : OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    1779                 :            : {
    1780                 :     363827 :     PyOSErrorObject *self = NULL;
    1781                 :     363827 :     PyObject *myerrno = NULL, *strerror = NULL;
    1782                 :     363827 :     PyObject *filename = NULL, *filename2 = NULL;
    1783                 :            : #ifdef MS_WINDOWS
    1784                 :            :     PyObject *winerror = NULL;
    1785                 :            : #endif
    1786                 :            : 
    1787                 :     363827 :     Py_INCREF(args);
    1788                 :            : 
    1789         [ +  + ]:     363827 :     if (!oserror_use_init(type)) {
    1790   [ -  +  -  - ]:     363748 :         if (!_PyArg_NoKeywords(type->tp_name, kwds))
    1791                 :          0 :             goto error;
    1792                 :            : 
    1793         [ -  + ]:     363748 :         if (oserror_parse_args(&args, &myerrno, &strerror,
    1794                 :            :                                &filename, &filename2
    1795                 :            : #ifdef MS_WINDOWS
    1796                 :            :                                , &winerror
    1797                 :            : #endif
    1798                 :            :             ))
    1799                 :          0 :             goto error;
    1800                 :            : 
    1801                 :     363748 :         struct _Py_exc_state *state = get_exc_state();
    1802   [ +  +  +  + ]:     363748 :         if (myerrno && PyLong_Check(myerrno) &&
    1803   [ +  -  +  + ]:     361411 :             state->errnomap && (PyObject *) type == PyExc_OSError) {
    1804                 :            :             PyObject *newtype;
    1805                 :     338879 :             newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
    1806         [ +  + ]:     338879 :             if (newtype) {
    1807                 :     293398 :                 type = _PyType_CAST(newtype);
    1808                 :            :             }
    1809         [ -  + ]:      45481 :             else if (PyErr_Occurred())
    1810                 :          0 :                 goto error;
    1811                 :            :         }
    1812                 :            :     }
    1813                 :            : 
    1814                 :     363827 :     self = (PyOSErrorObject *) type->tp_alloc(type, 0);
    1815         [ -  + ]:     363827 :     if (!self)
    1816                 :          0 :         goto error;
    1817                 :            : 
    1818                 :     363827 :     self->dict = NULL;
    1819                 :     363827 :     self->traceback = self->cause = self->context = NULL;
    1820                 :     363827 :     self->written = -1;
    1821                 :            : 
    1822         [ +  + ]:     363827 :     if (!oserror_use_init(type)) {
    1823         [ -  + ]:     363748 :         if (oserror_init(self, &args, myerrno, strerror, filename, filename2
    1824                 :            : #ifdef MS_WINDOWS
    1825                 :            :                          , winerror
    1826                 :            : #endif
    1827                 :            :             ))
    1828                 :          0 :             goto error;
    1829                 :            :     }
    1830                 :            :     else {
    1831                 :         79 :         self->args = PyTuple_New(0);
    1832         [ -  + ]:         79 :         if (self->args == NULL)
    1833                 :          0 :             goto error;
    1834                 :            :     }
    1835                 :            : 
    1836                 :     363827 :     Py_XDECREF(args);
    1837                 :     363827 :     return (PyObject *) self;
    1838                 :            : 
    1839                 :          0 : error:
    1840                 :          0 :     Py_XDECREF(args);
    1841                 :          0 :     Py_XDECREF(self);
    1842                 :          0 :     return NULL;
    1843                 :            : }
    1844                 :            : 
    1845                 :            : static int
    1846                 :     363755 : OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds)
    1847                 :            : {
    1848                 :     363755 :     PyObject *myerrno = NULL, *strerror = NULL;
    1849                 :     363755 :     PyObject *filename = NULL, *filename2 = NULL;
    1850                 :            : #ifdef MS_WINDOWS
    1851                 :            :     PyObject *winerror = NULL;
    1852                 :            : #endif
    1853                 :            : 
    1854         [ +  + ]:     363755 :     if (!oserror_use_init(Py_TYPE(self)))
    1855                 :            :         /* Everything already done in OSError_new */
    1856                 :     363748 :         return 0;
    1857                 :            : 
    1858   [ +  +  -  + ]:          7 :     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
    1859                 :          0 :         return -1;
    1860                 :            : 
    1861                 :          7 :     Py_INCREF(args);
    1862         [ -  + ]:          7 :     if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
    1863                 :            : #ifdef MS_WINDOWS
    1864                 :            :                            , &winerror
    1865                 :            : #endif
    1866                 :            :         ))
    1867                 :          0 :         goto error;
    1868                 :            : 
    1869         [ -  + ]:          7 :     if (oserror_init(self, &args, myerrno, strerror, filename, filename2
    1870                 :            : #ifdef MS_WINDOWS
    1871                 :            :                      , winerror
    1872                 :            : #endif
    1873                 :            :         ))
    1874                 :          0 :         goto error;
    1875                 :            : 
    1876                 :          7 :     return 0;
    1877                 :            : 
    1878                 :          0 : error:
    1879                 :          0 :     Py_DECREF(args);
    1880                 :          0 :     return -1;
    1881                 :            : }
    1882                 :            : 
    1883                 :            : static int
    1884                 :     363943 : OSError_clear(PyOSErrorObject *self)
    1885                 :            : {
    1886         [ +  + ]:     363943 :     Py_CLEAR(self->myerrno);
    1887         [ +  + ]:     363943 :     Py_CLEAR(self->strerror);
    1888         [ +  + ]:     363943 :     Py_CLEAR(self->filename);
    1889         [ +  + ]:     363943 :     Py_CLEAR(self->filename2);
    1890                 :            : #ifdef MS_WINDOWS
    1891                 :            :     Py_CLEAR(self->winerror);
    1892                 :            : #endif
    1893                 :     363943 :     return BaseException_clear((PyBaseExceptionObject *)self);
    1894                 :            : }
    1895                 :            : 
    1896                 :            : static void
    1897                 :     363817 : OSError_dealloc(PyOSErrorObject *self)
    1898                 :            : {
    1899                 :     363817 :     _PyObject_GC_UNTRACK(self);
    1900                 :     363817 :     OSError_clear(self);
    1901                 :     363817 :     Py_TYPE(self)->tp_free((PyObject *)self);
    1902                 :     363817 : }
    1903                 :            : 
    1904                 :            : static int
    1905                 :       1816 : OSError_traverse(PyOSErrorObject *self, visitproc visit,
    1906                 :            :         void *arg)
    1907                 :            : {
    1908   [ +  +  -  + ]:       1816 :     Py_VISIT(self->myerrno);
    1909   [ +  +  -  + ]:       1816 :     Py_VISIT(self->strerror);
    1910   [ +  +  -  + ]:       1816 :     Py_VISIT(self->filename);
    1911   [ +  +  -  + ]:       1816 :     Py_VISIT(self->filename2);
    1912                 :            : #ifdef MS_WINDOWS
    1913                 :            :     Py_VISIT(self->winerror);
    1914                 :            : #endif
    1915                 :       1816 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
    1916                 :            : }
    1917                 :            : 
    1918                 :            : static PyObject *
    1919                 :        179 : OSError_str(PyOSErrorObject *self)
    1920                 :            : {
    1921                 :            : #define OR_NONE(x) ((x)?(x):Py_None)
    1922                 :            : #ifdef MS_WINDOWS
    1923                 :            :     /* If available, winerror has the priority over myerrno */
    1924                 :            :     if (self->winerror && self->filename) {
    1925                 :            :         if (self->filename2) {
    1926                 :            :             return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R",
    1927                 :            :                                         OR_NONE(self->winerror),
    1928                 :            :                                         OR_NONE(self->strerror),
    1929                 :            :                                         self->filename,
    1930                 :            :                                         self->filename2);
    1931                 :            :         } else {
    1932                 :            :             return PyUnicode_FromFormat("[WinError %S] %S: %R",
    1933                 :            :                                         OR_NONE(self->winerror),
    1934                 :            :                                         OR_NONE(self->strerror),
    1935                 :            :                                         self->filename);
    1936                 :            :         }
    1937                 :            :     }
    1938                 :            :     if (self->winerror && self->strerror)
    1939                 :            :         return PyUnicode_FromFormat("[WinError %S] %S",
    1940                 :            :                                     self->winerror ? self->winerror: Py_None,
    1941                 :            :                                     self->strerror ? self->strerror: Py_None);
    1942                 :            : #endif
    1943         [ +  + ]:        179 :     if (self->filename) {
    1944         [ +  + ]:         87 :         if (self->filename2) {
    1945                 :          8 :             return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R",
    1946         [ +  - ]:          4 :                                         OR_NONE(self->myerrno),
    1947         [ +  - ]:          4 :                                         OR_NONE(self->strerror),
    1948                 :            :                                         self->filename,
    1949                 :            :                                         self->filename2);
    1950                 :            :         } else {
    1951                 :        166 :             return PyUnicode_FromFormat("[Errno %S] %S: %R",
    1952         [ +  - ]:         83 :                                         OR_NONE(self->myerrno),
    1953         [ +  - ]:         83 :                                         OR_NONE(self->strerror),
    1954                 :            :                                         self->filename);
    1955                 :            :         }
    1956                 :            :     }
    1957   [ +  +  +  - ]:         92 :     if (self->myerrno && self->strerror)
    1958                 :         25 :         return PyUnicode_FromFormat("[Errno %S] %S",
    1959                 :            :                                     self->myerrno, self->strerror);
    1960                 :         67 :     return BaseException_str((PyBaseExceptionObject *)self);
    1961                 :            : }
    1962                 :            : 
    1963                 :            : static PyObject *
    1964                 :         37 : OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored))
    1965                 :            : {
    1966                 :         37 :     PyObject *args = self->args;
    1967                 :         37 :     PyObject *res = NULL, *tmp;
    1968                 :            : 
    1969                 :            :     /* self->args is only the first two real arguments if there was a
    1970                 :            :      * file name given to OSError. */
    1971   [ +  +  +  + ]:         61 :     if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
    1972         [ +  + ]:         24 :         Py_ssize_t size = self->filename2 ? 5 : 3;
    1973                 :         24 :         args = PyTuple_New(size);
    1974         [ -  + ]:         24 :         if (!args)
    1975                 :          0 :             return NULL;
    1976                 :            : 
    1977                 :         24 :         tmp = PyTuple_GET_ITEM(self->args, 0);
    1978                 :         24 :         Py_INCREF(tmp);
    1979                 :         24 :         PyTuple_SET_ITEM(args, 0, tmp);
    1980                 :            : 
    1981                 :         24 :         tmp = PyTuple_GET_ITEM(self->args, 1);
    1982                 :         24 :         Py_INCREF(tmp);
    1983                 :         24 :         PyTuple_SET_ITEM(args, 1, tmp);
    1984                 :            : 
    1985                 :         24 :         Py_INCREF(self->filename);
    1986                 :         24 :         PyTuple_SET_ITEM(args, 2, self->filename);
    1987                 :            : 
    1988         [ +  + ]:         24 :         if (self->filename2) {
    1989                 :            :             /*
    1990                 :            :              * This tuple is essentially used as OSError(*args).
    1991                 :            :              * So, to recreate filename2, we need to pass in
    1992                 :            :              * winerror as well.
    1993                 :            :              */
    1994                 :          6 :             Py_INCREF(Py_None);
    1995                 :          6 :             PyTuple_SET_ITEM(args, 3, Py_None);
    1996                 :            : 
    1997                 :            :             /* filename2 */
    1998                 :          6 :             Py_INCREF(self->filename2);
    1999                 :          6 :             PyTuple_SET_ITEM(args, 4, self->filename2);
    2000                 :            :         }
    2001                 :            :     } else
    2002                 :         13 :         Py_INCREF(args);
    2003                 :            : 
    2004         [ -  + ]:         37 :     if (self->dict)
    2005                 :          0 :         res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
    2006                 :            :     else
    2007                 :         37 :         res = PyTuple_Pack(2, Py_TYPE(self), args);
    2008                 :         37 :     Py_DECREF(args);
    2009                 :         37 :     return res;
    2010                 :            : }
    2011                 :            : 
    2012                 :            : static PyObject *
    2013                 :         37 : OSError_written_get(PyOSErrorObject *self, void *context)
    2014                 :            : {
    2015         [ +  + ]:         37 :     if (self->written == -1) {
    2016                 :          7 :         PyErr_SetString(PyExc_AttributeError, "characters_written");
    2017                 :          7 :         return NULL;
    2018                 :            :     }
    2019                 :         30 :     return PyLong_FromSsize_t(self->written);
    2020                 :            : }
    2021                 :            : 
    2022                 :            : static int
    2023                 :          8 : OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context)
    2024                 :            : {
    2025         [ +  + ]:          8 :     if (arg == NULL) {
    2026         [ +  + ]:          7 :         if (self->written == -1) {
    2027                 :          6 :             PyErr_SetString(PyExc_AttributeError, "characters_written");
    2028                 :          6 :             return -1;
    2029                 :            :         }
    2030                 :          1 :         self->written = -1;
    2031                 :          1 :         return 0;
    2032                 :            :     }
    2033                 :            :     Py_ssize_t n;
    2034                 :          1 :     n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
    2035   [ -  +  -  - ]:          1 :     if (n == -1 && PyErr_Occurred())
    2036                 :          0 :         return -1;
    2037                 :          1 :     self->written = n;
    2038                 :          1 :     return 0;
    2039                 :            : }
    2040                 :            : 
    2041                 :            : static PyMemberDef OSError_members[] = {
    2042                 :            :     {"errno", T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
    2043                 :            :         PyDoc_STR("POSIX exception code")},
    2044                 :            :     {"strerror", T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
    2045                 :            :         PyDoc_STR("exception strerror")},
    2046                 :            :     {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
    2047                 :            :         PyDoc_STR("exception filename")},
    2048                 :            :     {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
    2049                 :            :         PyDoc_STR("second exception filename")},
    2050                 :            : #ifdef MS_WINDOWS
    2051                 :            :     {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
    2052                 :            :         PyDoc_STR("Win32 exception code")},
    2053                 :            : #endif
    2054                 :            :     {NULL}  /* Sentinel */
    2055                 :            : };
    2056                 :            : 
    2057                 :            : static PyMethodDef OSError_methods[] = {
    2058                 :            :     {"__reduce__", (PyCFunction)OSError_reduce, METH_NOARGS},
    2059                 :            :     {NULL}
    2060                 :            : };
    2061                 :            : 
    2062                 :            : static PyGetSetDef OSError_getset[] = {
    2063                 :            :     {"characters_written", (getter) OSError_written_get,
    2064                 :            :                            (setter) OSError_written_set, NULL},
    2065                 :            :     {NULL}
    2066                 :            : };
    2067                 :            : 
    2068                 :            : 
    2069                 :            : ComplexExtendsException(PyExc_Exception, OSError,
    2070                 :            :                         OSError, OSError_new,
    2071                 :            :                         OSError_methods, OSError_members, OSError_getset,
    2072                 :            :                         OSError_str,
    2073                 :            :                         "Base class for I/O related errors.");
    2074                 :            : 
    2075                 :            : 
    2076                 :            : /*
    2077                 :            :  *    Various OSError subclasses
    2078                 :            :  */
    2079                 :            : MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
    2080                 :            :                          "I/O operation would block.");
    2081                 :            : MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
    2082                 :            :                          "Connection error.");
    2083                 :            : MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
    2084                 :            :                          "Child process error.");
    2085                 :            : MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
    2086                 :            :                          "Broken pipe.");
    2087                 :            : MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
    2088                 :            :                          "Connection aborted.");
    2089                 :            : MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
    2090                 :            :                          "Connection refused.");
    2091                 :            : MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
    2092                 :            :                          "Connection reset.");
    2093                 :            : MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
    2094                 :            :                          "File already exists.");
    2095                 :            : MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
    2096                 :            :                          "File not found.");
    2097                 :            : MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
    2098                 :            :                          "Operation doesn't work on directories.");
    2099                 :            : MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
    2100                 :            :                          "Operation only works on directories.");
    2101                 :            : MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
    2102                 :            :                          "Interrupted by signal.");
    2103                 :            : MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
    2104                 :            :                          "Not enough permissions.");
    2105                 :            : MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
    2106                 :            :                          "Process not found.");
    2107                 :            : MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
    2108                 :            :                          "Timeout expired.");
    2109                 :            : 
    2110                 :            : /*
    2111                 :            :  *    EOFError extends Exception
    2112                 :            :  */
    2113                 :            : SimpleExtendsException(PyExc_Exception, EOFError,
    2114                 :            :                        "Read beyond end of file.");
    2115                 :            : 
    2116                 :            : 
    2117                 :            : /*
    2118                 :            :  *    RuntimeError extends Exception
    2119                 :            :  */
    2120                 :            : SimpleExtendsException(PyExc_Exception, RuntimeError,
    2121                 :            :                        "Unspecified run-time error.");
    2122                 :            : 
    2123                 :            : /*
    2124                 :            :  *    RecursionError extends RuntimeError
    2125                 :            :  */
    2126                 :            : SimpleExtendsException(PyExc_RuntimeError, RecursionError,
    2127                 :            :                        "Recursion limit exceeded.");
    2128                 :            : 
    2129                 :            : /*
    2130                 :            :  *    NotImplementedError extends RuntimeError
    2131                 :            :  */
    2132                 :            : SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
    2133                 :            :                        "Method or function hasn't been implemented yet.");
    2134                 :            : 
    2135                 :            : /*
    2136                 :            :  *    NameError extends Exception
    2137                 :            :  */
    2138                 :            : 
    2139                 :            : static int
    2140                 :        995 : NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds)
    2141                 :            : {
    2142                 :            :     static char *kwlist[] = {"name", NULL};
    2143                 :        995 :     PyObject *name = NULL;
    2144                 :            : 
    2145         [ -  + ]:        995 :     if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
    2146                 :          0 :         return -1;
    2147                 :            :     }
    2148                 :            : 
    2149                 :        995 :     PyObject *empty_tuple = PyTuple_New(0);
    2150         [ -  + ]:        995 :     if (!empty_tuple) {
    2151                 :          0 :         return -1;
    2152                 :            :     }
    2153         [ -  + ]:        995 :     if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
    2154                 :            :                                      &name)) {
    2155                 :          0 :         Py_DECREF(empty_tuple);
    2156                 :          0 :         return -1;
    2157                 :            :     }
    2158                 :        995 :     Py_DECREF(empty_tuple);
    2159                 :            : 
    2160                 :        995 :     Py_XINCREF(name);
    2161                 :        995 :     Py_XSETREF(self->name, name);
    2162                 :            : 
    2163                 :        995 :     return 0;
    2164                 :            : }
    2165                 :            : 
    2166                 :            : static int
    2167                 :       1016 : NameError_clear(PyNameErrorObject *self)
    2168                 :            : {
    2169         [ +  + ]:       1016 :     Py_CLEAR(self->name);
    2170                 :       1016 :     return BaseException_clear((PyBaseExceptionObject *)self);
    2171                 :            : }
    2172                 :            : 
    2173                 :            : static void
    2174                 :        995 : NameError_dealloc(PyNameErrorObject *self)
    2175                 :            : {
    2176                 :        995 :     _PyObject_GC_UNTRACK(self);
    2177                 :        995 :     NameError_clear(self);
    2178                 :        995 :     Py_TYPE(self)->tp_free((PyObject *)self);
    2179                 :        995 : }
    2180                 :            : 
    2181                 :            : static int
    2182                 :        156 : NameError_traverse(PyNameErrorObject *self, visitproc visit, void *arg)
    2183                 :            : {
    2184   [ +  +  -  + ]:        156 :     Py_VISIT(self->name);
    2185                 :        156 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
    2186                 :            : }
    2187                 :            : 
    2188                 :            : static PyMemberDef NameError_members[] = {
    2189                 :            :         {"name", T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
    2190                 :            :         {NULL}  /* Sentinel */
    2191                 :            : };
    2192                 :            : 
    2193                 :            : static PyMethodDef NameError_methods[] = {
    2194                 :            :         {NULL}  /* Sentinel */
    2195                 :            : };
    2196                 :            : 
    2197                 :            : ComplexExtendsException(PyExc_Exception, NameError,
    2198                 :            :                         NameError, 0,
    2199                 :            :                         NameError_methods, NameError_members,
    2200                 :            :                         0, BaseException_str, "Name not found globally.");
    2201                 :            : 
    2202                 :            : /*
    2203                 :            :  *    UnboundLocalError extends NameError
    2204                 :            :  */
    2205                 :            : 
    2206                 :            : MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
    2207                 :            :                        "Local name referenced but not bound to a value.");
    2208                 :            : 
    2209                 :            : /*
    2210                 :            :  *    AttributeError extends Exception
    2211                 :            :  */
    2212                 :            : 
    2213                 :            : static int
    2214                 :    1510875 : AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds)
    2215                 :            : {
    2216                 :            :     static char *kwlist[] = {"name", "obj", NULL};
    2217                 :    1510875 :     PyObject *name = NULL;
    2218                 :    1510875 :     PyObject *obj = NULL;
    2219                 :            : 
    2220         [ -  + ]:    1510875 :     if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
    2221                 :          0 :         return -1;
    2222                 :            :     }
    2223                 :            : 
    2224                 :    1510875 :     PyObject *empty_tuple = PyTuple_New(0);
    2225         [ -  + ]:    1510875 :     if (!empty_tuple) {
    2226                 :          0 :         return -1;
    2227                 :            :     }
    2228         [ -  + ]:    1510875 :     if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
    2229                 :            :                                      &name, &obj)) {
    2230                 :          0 :         Py_DECREF(empty_tuple);
    2231                 :          0 :         return -1;
    2232                 :            :     }
    2233                 :    1510875 :     Py_DECREF(empty_tuple);
    2234                 :            : 
    2235                 :    1510875 :     Py_XINCREF(name);
    2236                 :    1510875 :     Py_XSETREF(self->name, name);
    2237                 :            : 
    2238                 :    1510875 :     Py_XINCREF(obj);
    2239                 :    1510875 :     Py_XSETREF(self->obj, obj);
    2240                 :            : 
    2241                 :    1510875 :     return 0;
    2242                 :            : }
    2243                 :            : 
    2244                 :            : static int
    2245                 :    1510926 : AttributeError_clear(PyAttributeErrorObject *self)
    2246                 :            : {
    2247         [ +  + ]:    1510926 :     Py_CLEAR(self->obj);
    2248         [ +  + ]:    1510926 :     Py_CLEAR(self->name);
    2249                 :    1510926 :     return BaseException_clear((PyBaseExceptionObject *)self);
    2250                 :            : }
    2251                 :            : 
    2252                 :            : static void
    2253                 :    1510875 : AttributeError_dealloc(PyAttributeErrorObject *self)
    2254                 :            : {
    2255                 :    1510875 :     _PyObject_GC_UNTRACK(self);
    2256                 :    1510875 :     AttributeError_clear(self);
    2257                 :    1510875 :     Py_TYPE(self)->tp_free((PyObject *)self);
    2258                 :    1510875 : }
    2259                 :            : 
    2260                 :            : static int
    2261                 :        556 : AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg)
    2262                 :            : {
    2263   [ +  +  -  + ]:        556 :     Py_VISIT(self->obj);
    2264   [ +  +  -  + ]:        556 :     Py_VISIT(self->name);
    2265                 :        556 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
    2266                 :            : }
    2267                 :            : 
    2268                 :            : static PyMemberDef AttributeError_members[] = {
    2269                 :            :     {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
    2270                 :            :     {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
    2271                 :            :     {NULL}  /* Sentinel */
    2272                 :            : };
    2273                 :            : 
    2274                 :            : static PyMethodDef AttributeError_methods[] = {
    2275                 :            :     {NULL}  /* Sentinel */
    2276                 :            : };
    2277                 :            : 
    2278                 :            : ComplexExtendsException(PyExc_Exception, AttributeError,
    2279                 :            :                         AttributeError, 0,
    2280                 :            :                         AttributeError_methods, AttributeError_members,
    2281                 :            :                         0, BaseException_str, "Attribute not found.");
    2282                 :            : 
    2283                 :            : /*
    2284                 :            :  *    SyntaxError extends Exception
    2285                 :            :  */
    2286                 :            : 
    2287                 :            : static int
    2288                 :       2995 : SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
    2289                 :            : {
    2290                 :       2995 :     PyObject *info = NULL;
    2291                 :       2995 :     Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
    2292                 :            : 
    2293         [ -  + ]:       2995 :     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
    2294                 :          0 :         return -1;
    2295                 :            : 
    2296         [ +  + ]:       2995 :     if (lenargs >= 1) {
    2297                 :       2956 :         Py_INCREF(PyTuple_GET_ITEM(args, 0));
    2298                 :       2956 :         Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
    2299                 :            :     }
    2300         [ +  + ]:       2995 :     if (lenargs == 2) {
    2301                 :       2652 :         info = PyTuple_GET_ITEM(args, 1);
    2302                 :       2652 :         info = PySequence_Tuple(info);
    2303         [ -  + ]:       2652 :         if (!info) {
    2304                 :          0 :             return -1;
    2305                 :            :         }
    2306                 :            : 
    2307                 :       2652 :         self->end_lineno = NULL;
    2308                 :       2652 :         self->end_offset = NULL;
    2309         [ +  + ]:       2652 :         if (!PyArg_ParseTuple(info, "OOOO|OO",
    2310                 :            :                               &self->filename, &self->lineno,
    2311                 :            :                               &self->offset, &self->text,
    2312                 :            :                               &self->end_lineno, &self->end_offset)) {
    2313                 :          2 :             Py_DECREF(info);
    2314                 :          2 :             return -1;
    2315                 :            :         }
    2316                 :            : 
    2317                 :       2650 :         Py_INCREF(self->filename);
    2318                 :       2650 :         Py_INCREF(self->lineno);
    2319                 :       2650 :         Py_INCREF(self->offset);
    2320                 :       2650 :         Py_INCREF(self->text);
    2321                 :       2650 :         Py_XINCREF(self->end_lineno);
    2322                 :       2650 :         Py_XINCREF(self->end_offset);
    2323                 :       2650 :         Py_DECREF(info);
    2324                 :            : 
    2325   [ +  +  +  + ]:       2650 :         if (self->end_lineno != NULL && self->end_offset == NULL) {
    2326                 :          1 :             PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
    2327                 :          1 :             return -1;
    2328                 :            :         }
    2329                 :            :     }
    2330                 :       2992 :     return 0;
    2331                 :            : }
    2332                 :            : 
    2333                 :            : static int
    2334                 :       3046 : SyntaxError_clear(PySyntaxErrorObject *self)
    2335                 :            : {
    2336         [ +  + ]:       3046 :     Py_CLEAR(self->msg);
    2337         [ +  + ]:       3046 :     Py_CLEAR(self->filename);
    2338         [ +  + ]:       3046 :     Py_CLEAR(self->lineno);
    2339         [ +  + ]:       3046 :     Py_CLEAR(self->offset);
    2340         [ +  + ]:       3046 :     Py_CLEAR(self->end_lineno);
    2341         [ +  + ]:       3046 :     Py_CLEAR(self->end_offset);
    2342         [ +  + ]:       3046 :     Py_CLEAR(self->text);
    2343         [ -  + ]:       3046 :     Py_CLEAR(self->print_file_and_line);
    2344                 :       3046 :     return BaseException_clear((PyBaseExceptionObject *)self);
    2345                 :            : }
    2346                 :            : 
    2347                 :            : static void
    2348                 :       2995 : SyntaxError_dealloc(PySyntaxErrorObject *self)
    2349                 :            : {
    2350                 :       2995 :     _PyObject_GC_UNTRACK(self);
    2351                 :       2995 :     SyntaxError_clear(self);
    2352                 :       2995 :     Py_TYPE(self)->tp_free((PyObject *)self);
    2353                 :       2995 : }
    2354                 :            : 
    2355                 :            : static int
    2356                 :        191 : SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
    2357                 :            : {
    2358   [ +  -  -  + ]:        191 :     Py_VISIT(self->msg);
    2359   [ +  +  -  + ]:        191 :     Py_VISIT(self->filename);
    2360   [ +  +  -  + ]:        191 :     Py_VISIT(self->lineno);
    2361   [ +  +  -  + ]:        191 :     Py_VISIT(self->offset);
    2362   [ +  +  -  + ]:        191 :     Py_VISIT(self->end_lineno);
    2363   [ +  +  -  + ]:        191 :     Py_VISIT(self->end_offset);
    2364   [ +  +  -  + ]:        191 :     Py_VISIT(self->text);
    2365   [ -  +  -  - ]:        191 :     Py_VISIT(self->print_file_and_line);
    2366                 :        191 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
    2367                 :            : }
    2368                 :            : 
    2369                 :            : /* This is called "my_basename" instead of just "basename" to avoid name
    2370                 :            :    conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
    2371                 :            :    defined, and Python does define that. */
    2372                 :            : static PyObject*
    2373                 :       1737 : my_basename(PyObject *name)
    2374                 :            : {
    2375                 :            :     Py_ssize_t i, size, offset;
    2376                 :            :     int kind;
    2377                 :            :     const void *data;
    2378                 :            : 
    2379         [ -  + ]:       1737 :     if (PyUnicode_READY(name))
    2380                 :          0 :         return NULL;
    2381                 :       1737 :     kind = PyUnicode_KIND(name);
    2382                 :       1737 :     data = PyUnicode_DATA(name);
    2383                 :       1737 :     size = PyUnicode_GET_LENGTH(name);
    2384                 :       1737 :     offset = 0;
    2385         [ +  + ]:      35886 :     for(i=0; i < size; i++) {
    2386         [ +  + ]:      34149 :         if (PyUnicode_READ(kind, data, i) == SEP) {
    2387                 :        341 :             offset = i + 1;
    2388                 :            :         }
    2389                 :            :     }
    2390         [ +  + ]:       1737 :     if (offset != 0) {
    2391                 :         52 :         return PyUnicode_Substring(name, offset, size);
    2392                 :            :     }
    2393                 :            :     else {
    2394                 :       1685 :         Py_INCREF(name);
    2395                 :       1685 :         return name;
    2396                 :            :     }
    2397                 :            : }
    2398                 :            : 
    2399                 :            : 
    2400                 :            : static PyObject *
    2401                 :       1798 : SyntaxError_str(PySyntaxErrorObject *self)
    2402                 :            : {
    2403                 :       1798 :     int have_lineno = 0;
    2404                 :            :     PyObject *filename;
    2405                 :            :     PyObject *result;
    2406                 :            :     /* Below, we always ignore overflow errors, just printing -1.
    2407                 :            :        Still, we cannot allow an OverflowError to be raised, so
    2408                 :            :        we need to call PyLong_AsLongAndOverflow. */
    2409                 :            :     int overflow;
    2410                 :            : 
    2411                 :            :     /* XXX -- do all the additional formatting with filename and
    2412                 :            :        lineno here */
    2413                 :            : 
    2414   [ +  +  +  - ]:       1798 :     if (self->filename && PyUnicode_Check(self->filename)) {
    2415                 :       1737 :         filename = my_basename(self->filename);
    2416         [ -  + ]:       1737 :         if (filename == NULL)
    2417                 :          0 :             return NULL;
    2418                 :            :     } else {
    2419                 :         61 :         filename = NULL;
    2420                 :            :     }
    2421   [ +  +  +  + ]:       1798 :     have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
    2422                 :            : 
    2423   [ +  +  +  + ]:       1798 :     if (!filename && !have_lineno)
    2424         [ +  + ]:         59 :         return PyObject_Str(self->msg ? self->msg : Py_None);
    2425                 :            : 
    2426   [ +  +  +  + ]:       1739 :     if (filename && have_lineno)
    2427                 :       3466 :         result = PyUnicode_FromFormat("%S (%U, line %ld)",
    2428         [ +  - ]:       1733 :                    self->msg ? self->msg : Py_None,
    2429                 :            :                    filename,
    2430                 :            :                    PyLong_AsLongAndOverflow(self->lineno, &overflow));
    2431         [ +  + ]:          6 :     else if (filename)
    2432                 :          4 :         result = PyUnicode_FromFormat("%S (%U)",
    2433         [ +  - ]:          4 :                    self->msg ? self->msg : Py_None,
    2434                 :            :                    filename);
    2435                 :            :     else /* only have_lineno */
    2436                 :          4 :         result = PyUnicode_FromFormat("%S (line %ld)",
    2437         [ +  - ]:          2 :                    self->msg ? self->msg : Py_None,
    2438                 :            :                    PyLong_AsLongAndOverflow(self->lineno, &overflow));
    2439                 :       1739 :     Py_XDECREF(filename);
    2440                 :       1739 :     return result;
    2441                 :            : }
    2442                 :            : 
    2443                 :            : static PyMemberDef SyntaxError_members[] = {
    2444                 :            :     {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
    2445                 :            :         PyDoc_STR("exception msg")},
    2446                 :            :     {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
    2447                 :            :         PyDoc_STR("exception filename")},
    2448                 :            :     {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
    2449                 :            :         PyDoc_STR("exception lineno")},
    2450                 :            :     {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
    2451                 :            :         PyDoc_STR("exception offset")},
    2452                 :            :     {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
    2453                 :            :         PyDoc_STR("exception text")},
    2454                 :            :     {"end_lineno", T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
    2455                 :            :                    PyDoc_STR("exception end lineno")},
    2456                 :            :     {"end_offset", T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
    2457                 :            :                    PyDoc_STR("exception end offset")},
    2458                 :            :     {"print_file_and_line", T_OBJECT,
    2459                 :            :         offsetof(PySyntaxErrorObject, print_file_and_line), 0,
    2460                 :            :         PyDoc_STR("exception print_file_and_line")},
    2461                 :            :     {NULL}  /* Sentinel */
    2462                 :            : };
    2463                 :            : 
    2464                 :            : ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
    2465                 :            :                         0, 0, SyntaxError_members, 0,
    2466                 :            :                         SyntaxError_str, "Invalid syntax.");
    2467                 :            : 
    2468                 :            : 
    2469                 :            : /*
    2470                 :            :  *    IndentationError extends SyntaxError
    2471                 :            :  */
    2472                 :            : MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
    2473                 :            :                          "Improper indentation.");
    2474                 :            : 
    2475                 :            : 
    2476                 :            : /*
    2477                 :            :  *    TabError extends IndentationError
    2478                 :            :  */
    2479                 :            : MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
    2480                 :            :                          "Improper mixture of spaces and tabs.");
    2481                 :            : 
    2482                 :            : 
    2483                 :            : /*
    2484                 :            :  *    LookupError extends Exception
    2485                 :            :  */
    2486                 :            : SimpleExtendsException(PyExc_Exception, LookupError,
    2487                 :            :                        "Base class for lookup errors.");
    2488                 :            : 
    2489                 :            : 
    2490                 :            : /*
    2491                 :            :  *    IndexError extends LookupError
    2492                 :            :  */
    2493                 :            : SimpleExtendsException(PyExc_LookupError, IndexError,
    2494                 :            :                        "Sequence index out of range.");
    2495                 :            : 
    2496                 :            : 
    2497                 :            : /*
    2498                 :            :  *    KeyError extends LookupError
    2499                 :            :  */
    2500                 :            : static PyObject *
    2501                 :         45 : KeyError_str(PyBaseExceptionObject *self)
    2502                 :            : {
    2503                 :            :     /* If args is a tuple of exactly one item, apply repr to args[0].
    2504                 :            :        This is done so that e.g. the exception raised by {}[''] prints
    2505                 :            :          KeyError: ''
    2506                 :            :        rather than the confusing
    2507                 :            :          KeyError
    2508                 :            :        alone.  The downside is that if KeyError is raised with an explanatory
    2509                 :            :        string, that string will be displayed in quotes.  Too bad.
    2510                 :            :        If args is anything else, use the default BaseException__str__().
    2511                 :            :     */
    2512         [ +  + ]:         45 :     if (PyTuple_GET_SIZE(self->args) == 1) {
    2513                 :         23 :         return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
    2514                 :            :     }
    2515                 :         22 :     return BaseException_str(self);
    2516                 :            : }
    2517                 :            : 
    2518                 :            : ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
    2519                 :            :                         0, 0, 0, 0, KeyError_str, "Mapping key not found.");
    2520                 :            : 
    2521                 :            : 
    2522                 :            : /*
    2523                 :            :  *    ValueError extends Exception
    2524                 :            :  */
    2525                 :            : SimpleExtendsException(PyExc_Exception, ValueError,
    2526                 :            :                        "Inappropriate argument value (of correct type).");
    2527                 :            : 
    2528                 :            : /*
    2529                 :            :  *    UnicodeError extends ValueError
    2530                 :            :  */
    2531                 :            : 
    2532                 :            : SimpleExtendsException(PyExc_ValueError, UnicodeError,
    2533                 :            :                        "Unicode related error.");
    2534                 :            : 
    2535                 :            : static PyObject *
    2536                 :       8941 : get_string(PyObject *attr, const char *name)
    2537                 :            : {
    2538         [ -  + ]:       8941 :     if (!attr) {
    2539                 :          0 :         PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
    2540                 :          0 :         return NULL;
    2541                 :            :     }
    2542                 :            : 
    2543         [ +  + ]:       8941 :     if (!PyBytes_Check(attr)) {
    2544                 :          8 :         PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
    2545                 :          8 :         return NULL;
    2546                 :            :     }
    2547                 :       8933 :     Py_INCREF(attr);
    2548                 :       8933 :     return attr;
    2549                 :            : }
    2550                 :            : 
    2551                 :            : static PyObject *
    2552                 :      19669 : get_unicode(PyObject *attr, const char *name)
    2553                 :            : {
    2554         [ -  + ]:      19669 :     if (!attr) {
    2555                 :          0 :         PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
    2556                 :          0 :         return NULL;
    2557                 :            :     }
    2558                 :            : 
    2559         [ +  + ]:      19669 :     if (!PyUnicode_Check(attr)) {
    2560                 :          1 :         PyErr_Format(PyExc_TypeError,
    2561                 :            :                      "%.200s attribute must be unicode", name);
    2562                 :          1 :         return NULL;
    2563                 :            :     }
    2564                 :      19668 :     Py_INCREF(attr);
    2565                 :      19668 :     return attr;
    2566                 :            : }
    2567                 :            : 
    2568                 :            : static int
    2569                 :      10563 : set_unicodefromstring(PyObject **attr, const char *value)
    2570                 :            : {
    2571                 :      10563 :     PyObject *obj = PyUnicode_FromString(value);
    2572         [ -  + ]:      10563 :     if (!obj)
    2573                 :          0 :         return -1;
    2574                 :      10563 :     Py_XSETREF(*attr, obj);
    2575                 :      10563 :     return 0;
    2576                 :            : }
    2577                 :            : 
    2578                 :            : PyObject *
    2579                 :         53 : PyUnicodeEncodeError_GetEncoding(PyObject *exc)
    2580                 :            : {
    2581                 :         53 :     return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
    2582                 :            : }
    2583                 :            : 
    2584                 :            : PyObject *
    2585                 :       1348 : PyUnicodeDecodeError_GetEncoding(PyObject *exc)
    2586                 :            : {
    2587                 :       1348 :     return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
    2588                 :            : }
    2589                 :            : 
    2590                 :            : PyObject *
    2591                 :       4253 : PyUnicodeEncodeError_GetObject(PyObject *exc)
    2592                 :            : {
    2593                 :       4253 :     return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
    2594                 :            : }
    2595                 :            : 
    2596                 :            : PyObject *
    2597                 :       4606 : PyUnicodeDecodeError_GetObject(PyObject *exc)
    2598                 :            : {
    2599                 :       4606 :     return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
    2600                 :            : }
    2601                 :            : 
    2602                 :            : PyObject *
    2603                 :         12 : PyUnicodeTranslateError_GetObject(PyObject *exc)
    2604                 :            : {
    2605                 :         12 :     return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
    2606                 :            : }
    2607                 :            : 
    2608                 :            : int
    2609                 :       5290 : PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
    2610                 :            : {
    2611                 :            :     Py_ssize_t size;
    2612                 :       5290 :     PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
    2613                 :            :                                 "object");
    2614         [ +  + ]:       5290 :     if (!obj)
    2615                 :          1 :         return -1;
    2616                 :       5289 :     *start = ((PyUnicodeErrorObject *)exc)->start;
    2617                 :       5289 :     size = PyUnicode_GET_LENGTH(obj);
    2618         [ -  + ]:       5289 :     if (*start<0)
    2619                 :          0 :         *start = 0; /*XXX check for values <0*/
    2620         [ -  + ]:       5289 :     if (*start>=size)
    2621                 :          0 :         *start = size-1;
    2622                 :       5289 :     Py_DECREF(obj);
    2623                 :       5289 :     return 0;
    2624                 :            : }
    2625                 :            : 
    2626                 :            : 
    2627                 :            : int
    2628                 :       1411 : PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
    2629                 :            : {
    2630                 :            :     Py_ssize_t size;
    2631                 :       1411 :     PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
    2632         [ -  + ]:       1411 :     if (!obj)
    2633                 :          0 :         return -1;
    2634                 :       1411 :     size = PyBytes_GET_SIZE(obj);
    2635                 :       1411 :     *start = ((PyUnicodeErrorObject *)exc)->start;
    2636         [ -  + ]:       1411 :     if (*start<0)
    2637                 :          0 :         *start = 0;
    2638         [ -  + ]:       1411 :     if (*start>=size)
    2639                 :          0 :         *start = size-1;
    2640                 :       1411 :     Py_DECREF(obj);
    2641                 :       1411 :     return 0;
    2642                 :            : }
    2643                 :            : 
    2644                 :            : 
    2645                 :            : int
    2646                 :         13 : PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
    2647                 :            : {
    2648                 :         13 :     return PyUnicodeEncodeError_GetStart(exc, start);
    2649                 :            : }
    2650                 :            : 
    2651                 :            : 
    2652                 :            : int
    2653                 :       8901 : PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
    2654                 :            : {
    2655                 :       8901 :     ((PyUnicodeErrorObject *)exc)->start = start;
    2656                 :       8901 :     return 0;
    2657                 :            : }
    2658                 :            : 
    2659                 :            : 
    2660                 :            : int
    2661                 :       1662 : PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
    2662                 :            : {
    2663                 :       1662 :     ((PyUnicodeErrorObject *)exc)->start = start;
    2664                 :       1662 :     return 0;
    2665                 :            : }
    2666                 :            : 
    2667                 :            : 
    2668                 :            : int
    2669                 :          0 : PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
    2670                 :            : {
    2671                 :          0 :     ((PyUnicodeErrorObject *)exc)->start = start;
    2672                 :          0 :     return 0;
    2673                 :            : }
    2674                 :            : 
    2675                 :            : 
    2676                 :            : int
    2677                 :       8713 : PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
    2678                 :            : {
    2679                 :            :     Py_ssize_t size;
    2680                 :       8713 :     PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
    2681                 :            :                                 "object");
    2682         [ -  + ]:       8713 :     if (!obj)
    2683                 :          0 :         return -1;
    2684                 :       8713 :     *end = ((PyUnicodeErrorObject *)exc)->end;
    2685                 :       8713 :     size = PyUnicode_GET_LENGTH(obj);
    2686         [ -  + ]:       8713 :     if (*end<1)
    2687                 :          0 :         *end = 1;
    2688         [ -  + ]:       8713 :     if (*end>size)
    2689                 :          0 :         *end = size;
    2690                 :       8713 :     Py_DECREF(obj);
    2691                 :       8713 :     return 0;
    2692                 :            : }
    2693                 :            : 
    2694                 :            : 
    2695                 :            : int
    2696                 :       2924 : PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
    2697                 :            : {
    2698                 :            :     Py_ssize_t size;
    2699                 :       2924 :     PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
    2700         [ +  + ]:       2924 :     if (!obj)
    2701                 :          1 :         return -1;
    2702                 :       2923 :     size = PyBytes_GET_SIZE(obj);
    2703                 :       2923 :     *end = ((PyUnicodeErrorObject *)exc)->end;
    2704         [ -  + ]:       2923 :     if (*end<1)
    2705                 :          0 :         *end = 1;
    2706         [ -  + ]:       2923 :     if (*end>size)
    2707                 :          0 :         *end = size;
    2708                 :       2923 :     Py_DECREF(obj);
    2709                 :       2923 :     return 0;
    2710                 :            : }
    2711                 :            : 
    2712                 :            : 
    2713                 :            : int
    2714                 :         14 : PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
    2715                 :            : {
    2716                 :         14 :     return PyUnicodeEncodeError_GetEnd(exc, end);
    2717                 :            : }
    2718                 :            : 
    2719                 :            : 
    2720                 :            : int
    2721                 :       8901 : PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
    2722                 :            : {
    2723                 :       8901 :     ((PyUnicodeErrorObject *)exc)->end = end;
    2724                 :       8901 :     return 0;
    2725                 :            : }
    2726                 :            : 
    2727                 :            : 
    2728                 :            : int
    2729                 :       1662 : PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
    2730                 :            : {
    2731                 :       1662 :     ((PyUnicodeErrorObject *)exc)->end = end;
    2732                 :       1662 :     return 0;
    2733                 :            : }
    2734                 :            : 
    2735                 :            : 
    2736                 :            : int
    2737                 :          0 : PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
    2738                 :            : {
    2739                 :          0 :     ((PyUnicodeErrorObject *)exc)->end = end;
    2740                 :          0 :     return 0;
    2741                 :            : }
    2742                 :            : 
    2743                 :            : PyObject *
    2744                 :          0 : PyUnicodeEncodeError_GetReason(PyObject *exc)
    2745                 :            : {
    2746                 :          0 :     return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
    2747                 :            : }
    2748                 :            : 
    2749                 :            : 
    2750                 :            : PyObject *
    2751                 :          0 : PyUnicodeDecodeError_GetReason(PyObject *exc)
    2752                 :            : {
    2753                 :          0 :     return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
    2754                 :            : }
    2755                 :            : 
    2756                 :            : 
    2757                 :            : PyObject *
    2758                 :          0 : PyUnicodeTranslateError_GetReason(PyObject *exc)
    2759                 :            : {
    2760                 :          0 :     return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
    2761                 :            : }
    2762                 :            : 
    2763                 :            : 
    2764                 :            : int
    2765                 :       8901 : PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
    2766                 :            : {
    2767                 :       8901 :     return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
    2768                 :            :                                  reason);
    2769                 :            : }
    2770                 :            : 
    2771                 :            : 
    2772                 :            : int
    2773                 :       1662 : PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
    2774                 :            : {
    2775                 :       1662 :     return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
    2776                 :            :                                  reason);
    2777                 :            : }
    2778                 :            : 
    2779                 :            : 
    2780                 :            : int
    2781                 :          0 : PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
    2782                 :            : {
    2783                 :          0 :     return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
    2784                 :            :                                  reason);
    2785                 :            : }
    2786                 :            : 
    2787                 :            : 
    2788                 :            : static int
    2789                 :       8238 : UnicodeError_clear(PyUnicodeErrorObject *self)
    2790                 :            : {
    2791         [ +  + ]:       8238 :     Py_CLEAR(self->encoding);
    2792         [ +  + ]:       8238 :     Py_CLEAR(self->object);
    2793         [ +  + ]:       8238 :     Py_CLEAR(self->reason);
    2794                 :       8238 :     return BaseException_clear((PyBaseExceptionObject *)self);
    2795                 :            : }
    2796                 :            : 
    2797                 :            : static void
    2798                 :       8236 : UnicodeError_dealloc(PyUnicodeErrorObject *self)
    2799                 :            : {
    2800                 :       8236 :     _PyObject_GC_UNTRACK(self);
    2801                 :       8236 :     UnicodeError_clear(self);
    2802                 :       8236 :     Py_TYPE(self)->tp_free((PyObject *)self);
    2803                 :       8236 : }
    2804                 :            : 
    2805                 :            : static int
    2806                 :         16 : UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
    2807                 :            : {
    2808   [ +  -  -  + ]:         16 :     Py_VISIT(self->encoding);
    2809   [ +  -  -  + ]:         16 :     Py_VISIT(self->object);
    2810   [ +  -  -  + ]:         16 :     Py_VISIT(self->reason);
    2811                 :         16 :     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
    2812                 :            : }
    2813                 :            : 
    2814                 :            : static PyMemberDef UnicodeError_members[] = {
    2815                 :            :     {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
    2816                 :            :         PyDoc_STR("exception encoding")},
    2817                 :            :     {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
    2818                 :            :         PyDoc_STR("exception object")},
    2819                 :            :     {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
    2820                 :            :         PyDoc_STR("exception start")},
    2821                 :            :     {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
    2822                 :            :         PyDoc_STR("exception end")},
    2823                 :            :     {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
    2824                 :            :         PyDoc_STR("exception reason")},
    2825                 :            :     {NULL}  /* Sentinel */
    2826                 :            : };
    2827                 :            : 
    2828                 :            : 
    2829                 :            : /*
    2830                 :            :  *    UnicodeEncodeError extends UnicodeError
    2831                 :            :  */
    2832                 :            : 
    2833                 :            : static int
    2834                 :       2343 : UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
    2835                 :            : {
    2836                 :            :     PyUnicodeErrorObject *err;
    2837                 :            : 
    2838         [ -  + ]:       2343 :     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
    2839                 :          0 :         return -1;
    2840                 :            : 
    2841                 :       2343 :     err = (PyUnicodeErrorObject *)self;
    2842                 :            : 
    2843         [ -  + ]:       2343 :     Py_CLEAR(err->encoding);
    2844         [ -  + ]:       2343 :     Py_CLEAR(err->object);
    2845         [ -  + ]:       2343 :     Py_CLEAR(err->reason);
    2846                 :            : 
    2847         [ +  + ]:       2343 :     if (!PyArg_ParseTuple(args, "UUnnU",
    2848                 :            :                           &err->encoding, &err->object,
    2849                 :            :                           &err->start, &err->end, &err->reason)) {
    2850                 :        163 :         err->encoding = err->object = err->reason = NULL;
    2851                 :        163 :         return -1;
    2852                 :            :     }
    2853                 :            : 
    2854                 :       2180 :     Py_INCREF(err->encoding);
    2855                 :       2180 :     Py_INCREF(err->object);
    2856                 :       2180 :     Py_INCREF(err->reason);
    2857                 :            : 
    2858                 :       2180 :     return 0;
    2859                 :            : }
    2860                 :            : 
    2861                 :            : static PyObject *
    2862                 :         22 : UnicodeEncodeError_str(PyObject *self)
    2863                 :            : {
    2864                 :         22 :     PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
    2865                 :         22 :     PyObject *result = NULL;
    2866                 :         22 :     PyObject *reason_str = NULL;
    2867                 :         22 :     PyObject *encoding_str = NULL;
    2868                 :            : 
    2869         [ +  + ]:         22 :     if (!uself->object)
    2870                 :            :         /* Not properly initialized. */
    2871                 :          1 :         return PyUnicode_FromString("");
    2872                 :            : 
    2873                 :            :     /* Get reason and encoding as strings, which they might not be if
    2874                 :            :        they've been modified after we were constructed. */
    2875                 :         21 :     reason_str = PyObject_Str(uself->reason);
    2876         [ -  + ]:         21 :     if (reason_str == NULL)
    2877                 :          0 :         goto done;
    2878                 :         21 :     encoding_str = PyObject_Str(uself->encoding);
    2879         [ -  + ]:         21 :     if (encoding_str == NULL)
    2880                 :          0 :         goto done;
    2881                 :            : 
    2882   [ +  +  +  + ]:         36 :     if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
    2883                 :         15 :         Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
    2884                 :            :         const char *fmt;
    2885         [ +  + ]:         15 :         if (badchar <= 0xff)
    2886                 :          8 :             fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
    2887         [ +  + ]:          7 :         else if (badchar <= 0xffff)
    2888                 :          6 :             fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
    2889                 :            :         else
    2890                 :          1 :             fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
    2891                 :         15 :         result = PyUnicode_FromFormat(
    2892                 :            :             fmt,
    2893                 :            :             encoding_str,
    2894                 :            :             (int)badchar,
    2895                 :            :             uself->start,
    2896                 :            :             reason_str);
    2897                 :            :     }
    2898                 :            :     else {
    2899                 :          6 :         result = PyUnicode_FromFormat(
    2900                 :            :             "'%U' codec can't encode characters in position %zd-%zd: %U",
    2901                 :            :             encoding_str,
    2902                 :            :             uself->start,
    2903                 :          6 :             uself->end-1,
    2904                 :            :             reason_str);
    2905                 :            :     }
    2906                 :         21 : done:
    2907                 :         21 :     Py_XDECREF(reason_str);
    2908                 :         21 :     Py_XDECREF(encoding_str);
    2909                 :         21 :     return result;
    2910                 :            : }
    2911                 :            : 
    2912                 :            : static PyTypeObject _PyExc_UnicodeEncodeError = {
    2913                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
    2914                 :            :     "UnicodeEncodeError",
    2915                 :            :     sizeof(PyUnicodeErrorObject), 0,
    2916                 :            :     (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    2917                 :            :     (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
    2918                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    2919                 :            :     PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
    2920                 :            :     (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
    2921                 :            :     0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
    2922                 :            :     (initproc)UnicodeEncodeError_init, 0, BaseException_new,
    2923                 :            : };
    2924                 :            : PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
    2925                 :            : 
    2926                 :            : 
    2927                 :            : /*
    2928                 :            :  *    UnicodeDecodeError extends UnicodeError
    2929                 :            :  */
    2930                 :            : 
    2931                 :            : static int
    2932                 :       5746 : UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
    2933                 :            : {
    2934                 :            :     PyUnicodeErrorObject *ude;
    2935                 :            : 
    2936         [ -  + ]:       5746 :     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
    2937                 :          0 :         return -1;
    2938                 :            : 
    2939                 :       5746 :     ude = (PyUnicodeErrorObject *)self;
    2940                 :            : 
    2941         [ -  + ]:       5746 :     Py_CLEAR(ude->encoding);
    2942         [ -  + ]:       5746 :     Py_CLEAR(ude->object);
    2943         [ -  + ]:       5746 :     Py_CLEAR(ude->reason);
    2944                 :            : 
    2945         [ +  + ]:       5746 :     if (!PyArg_ParseTuple(args, "UOnnU",
    2946                 :            :                           &ude->encoding, &ude->object,
    2947                 :            :                           &ude->start, &ude->end, &ude->reason)) {
    2948                 :         57 :              ude->encoding = ude->object = ude->reason = NULL;
    2949                 :         57 :              return -1;
    2950                 :            :     }
    2951                 :            : 
    2952                 :       5689 :     Py_INCREF(ude->encoding);
    2953                 :       5689 :     Py_INCREF(ude->object);
    2954                 :       5689 :     Py_INCREF(ude->reason);
    2955                 :            : 
    2956         [ +  + ]:       5689 :     if (!PyBytes_Check(ude->object)) {
    2957                 :            :         Py_buffer view;
    2958         [ -  + ]:         36 :         if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
    2959                 :          0 :             goto error;
    2960                 :         36 :         Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len));
    2961                 :         36 :         PyBuffer_Release(&view);
    2962         [ -  + ]:         36 :         if (!ude->object)
    2963                 :          0 :             goto error;
    2964                 :            :     }
    2965                 :       5689 :     return 0;
    2966                 :            : 
    2967                 :          0 : error:
    2968         [ #  # ]:          0 :     Py_CLEAR(ude->encoding);
    2969         [ #  # ]:          0 :     Py_CLEAR(ude->object);
    2970         [ #  # ]:          0 :     Py_CLEAR(ude->reason);
    2971                 :          0 :     return -1;
    2972                 :            : }
    2973                 :            : 
    2974                 :            : static PyObject *
    2975                 :        760 : UnicodeDecodeError_str(PyObject *self)
    2976                 :            : {
    2977                 :        760 :     PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
    2978                 :        760 :     PyObject *result = NULL;
    2979                 :        760 :     PyObject *reason_str = NULL;
    2980                 :        760 :     PyObject *encoding_str = NULL;
    2981                 :            : 
    2982         [ +  + ]:        760 :     if (!uself->object)
    2983                 :            :         /* Not properly initialized. */
    2984                 :          1 :         return PyUnicode_FromString("");
    2985                 :            : 
    2986                 :            :     /* Get reason and encoding as strings, which they might not be if
    2987                 :            :        they've been modified after we were constructed. */
    2988                 :        759 :     reason_str = PyObject_Str(uself->reason);
    2989         [ -  + ]:        759 :     if (reason_str == NULL)
    2990                 :          0 :         goto done;
    2991                 :        759 :     encoding_str = PyObject_Str(uself->encoding);
    2992         [ -  + ]:        759 :     if (encoding_str == NULL)
    2993                 :          0 :         goto done;
    2994                 :            : 
    2995   [ +  +  +  + ]:        835 :     if (uself->start < PyBytes_GET_SIZE(uself->object) && uself->end == uself->start+1) {
    2996                 :         76 :         int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
    2997                 :         76 :         result = PyUnicode_FromFormat(
    2998                 :            :             "'%U' codec can't decode byte 0x%02x in position %zd: %U",
    2999                 :            :             encoding_str,
    3000                 :            :             byte,
    3001                 :            :             uself->start,
    3002                 :            :             reason_str);
    3003                 :            :     }
    3004                 :            :     else {
    3005                 :        683 :         result = PyUnicode_FromFormat(
    3006                 :            :             "'%U' codec can't decode bytes in position %zd-%zd: %U",
    3007                 :            :             encoding_str,
    3008                 :            :             uself->start,
    3009                 :        683 :             uself->end-1,
    3010                 :            :             reason_str
    3011                 :            :             );
    3012                 :            :     }
    3013                 :        759 : done:
    3014                 :        759 :     Py_XDECREF(reason_str);
    3015                 :        759 :     Py_XDECREF(encoding_str);
    3016                 :        759 :     return result;
    3017                 :            : }
    3018                 :            : 
    3019                 :            : static PyTypeObject _PyExc_UnicodeDecodeError = {
    3020                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
    3021                 :            :     "UnicodeDecodeError",
    3022                 :            :     sizeof(PyUnicodeErrorObject), 0,
    3023                 :            :     (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    3024                 :            :     (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
    3025                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    3026                 :            :     PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
    3027                 :            :     (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
    3028                 :            :     0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
    3029                 :            :     (initproc)UnicodeDecodeError_init, 0, BaseException_new,
    3030                 :            : };
    3031                 :            : PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
    3032                 :            : 
    3033                 :            : PyObject *
    3034                 :       5639 : PyUnicodeDecodeError_Create(
    3035                 :            :     const char *encoding, const char *object, Py_ssize_t length,
    3036                 :            :     Py_ssize_t start, Py_ssize_t end, const char *reason)
    3037                 :            : {
    3038                 :       5639 :     return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
    3039                 :            :                                  encoding, object, length, start, end, reason);
    3040                 :            : }
    3041                 :            : 
    3042                 :            : 
    3043                 :            : /*
    3044                 :            :  *    UnicodeTranslateError extends UnicodeError
    3045                 :            :  */
    3046                 :            : 
    3047                 :            : static int
    3048                 :        144 : UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
    3049                 :            :                            PyObject *kwds)
    3050                 :            : {
    3051         [ -  + ]:        144 :     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
    3052                 :          0 :         return -1;
    3053                 :            : 
    3054         [ -  + ]:        144 :     Py_CLEAR(self->object);
    3055         [ -  + ]:        144 :     Py_CLEAR(self->reason);
    3056                 :            : 
    3057         [ +  + ]:        144 :     if (!PyArg_ParseTuple(args, "UnnU",
    3058                 :            :                           &self->object,
    3059                 :            :                           &self->start, &self->end, &self->reason)) {
    3060                 :        111 :         self->object = self->reason = NULL;
    3061                 :        111 :         return -1;
    3062                 :            :     }
    3063                 :            : 
    3064                 :         33 :     Py_INCREF(self->object);
    3065                 :         33 :     Py_INCREF(self->reason);
    3066                 :            : 
    3067                 :         33 :     return 0;
    3068                 :            : }
    3069                 :            : 
    3070                 :            : 
    3071                 :            : static PyObject *
    3072                 :         11 : UnicodeTranslateError_str(PyObject *self)
    3073                 :            : {
    3074                 :         11 :     PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
    3075                 :         11 :     PyObject *result = NULL;
    3076                 :         11 :     PyObject *reason_str = NULL;
    3077                 :            : 
    3078         [ +  + ]:         11 :     if (!uself->object)
    3079                 :            :         /* Not properly initialized. */
    3080                 :          1 :         return PyUnicode_FromString("");
    3081                 :            : 
    3082                 :            :     /* Get reason as a string, which it might not be if it's been
    3083                 :            :        modified after we were constructed. */
    3084                 :         10 :     reason_str = PyObject_Str(uself->reason);
    3085         [ -  + ]:         10 :     if (reason_str == NULL)
    3086                 :          0 :         goto done;
    3087                 :            : 
    3088   [ +  +  +  + ]:         16 :     if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
    3089                 :          6 :         Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
    3090                 :            :         const char *fmt;
    3091         [ +  + ]:          6 :         if (badchar <= 0xff)
    3092                 :          2 :             fmt = "can't translate character '\\x%02x' in position %zd: %U";
    3093         [ +  + ]:          4 :         else if (badchar <= 0xffff)
    3094                 :          3 :             fmt = "can't translate character '\\u%04x' in position %zd: %U";
    3095                 :            :         else
    3096                 :          1 :             fmt = "can't translate character '\\U%08x' in position %zd: %U";
    3097                 :          6 :         result = PyUnicode_FromFormat(
    3098                 :            :             fmt,
    3099                 :            :             (int)badchar,
    3100                 :            :             uself->start,
    3101                 :            :             reason_str
    3102                 :            :         );
    3103                 :            :     } else {
    3104                 :          4 :         result = PyUnicode_FromFormat(
    3105                 :            :             "can't translate characters in position %zd-%zd: %U",
    3106                 :            :             uself->start,
    3107                 :          4 :             uself->end-1,
    3108                 :            :             reason_str
    3109                 :            :             );
    3110                 :            :     }
    3111                 :         10 : done:
    3112                 :         10 :     Py_XDECREF(reason_str);
    3113                 :         10 :     return result;
    3114                 :            : }
    3115                 :            : 
    3116                 :            : static PyTypeObject _PyExc_UnicodeTranslateError = {
    3117                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
    3118                 :            :     "UnicodeTranslateError",
    3119                 :            :     sizeof(PyUnicodeErrorObject), 0,
    3120                 :            :     (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    3121                 :            :     (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
    3122                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    3123                 :            :     PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
    3124                 :            :     (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
    3125                 :            :     0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
    3126                 :            :     (initproc)UnicodeTranslateError_init, 0, BaseException_new,
    3127                 :            : };
    3128                 :            : PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
    3129                 :            : 
    3130                 :            : PyObject *
    3131                 :          0 : _PyUnicodeTranslateError_Create(
    3132                 :            :     PyObject *object,
    3133                 :            :     Py_ssize_t start, Py_ssize_t end, const char *reason)
    3134                 :            : {
    3135                 :          0 :     return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
    3136                 :            :                                  object, start, end, reason);
    3137                 :            : }
    3138                 :            : 
    3139                 :            : /*
    3140                 :            :  *    AssertionError extends Exception
    3141                 :            :  */
    3142                 :            : SimpleExtendsException(PyExc_Exception, AssertionError,
    3143                 :            :                        "Assertion failed.");
    3144                 :            : 
    3145                 :            : 
    3146                 :            : /*
    3147                 :            :  *    ArithmeticError extends Exception
    3148                 :            :  */
    3149                 :            : SimpleExtendsException(PyExc_Exception, ArithmeticError,
    3150                 :            :                        "Base class for arithmetic errors.");
    3151                 :            : 
    3152                 :            : 
    3153                 :            : /*
    3154                 :            :  *    FloatingPointError extends ArithmeticError
    3155                 :            :  */
    3156                 :            : SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
    3157                 :            :                        "Floating point operation failed.");
    3158                 :            : 
    3159                 :            : 
    3160                 :            : /*
    3161                 :            :  *    OverflowError extends ArithmeticError
    3162                 :            :  */
    3163                 :            : SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
    3164                 :            :                        "Result too large to be represented.");
    3165                 :            : 
    3166                 :            : 
    3167                 :            : /*
    3168                 :            :  *    ZeroDivisionError extends ArithmeticError
    3169                 :            :  */
    3170                 :            : SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
    3171                 :            :           "Second argument to a division or modulo operation was zero.");
    3172                 :            : 
    3173                 :            : 
    3174                 :            : /*
    3175                 :            :  *    SystemError extends Exception
    3176                 :            :  */
    3177                 :            : SimpleExtendsException(PyExc_Exception, SystemError,
    3178                 :            :     "Internal error in the Python interpreter.\n"
    3179                 :            :     "\n"
    3180                 :            :     "Please report this to the Python maintainer, along with the traceback,\n"
    3181                 :            :     "the Python version, and the hardware/OS platform and version.");
    3182                 :            : 
    3183                 :            : 
    3184                 :            : /*
    3185                 :            :  *    ReferenceError extends Exception
    3186                 :            :  */
    3187                 :            : SimpleExtendsException(PyExc_Exception, ReferenceError,
    3188                 :            :                        "Weak ref proxy used after referent went away.");
    3189                 :            : 
    3190                 :            : 
    3191                 :            : /*
    3192                 :            :  *    MemoryError extends Exception
    3193                 :            :  */
    3194                 :            : 
    3195                 :            : #define MEMERRORS_SAVE 16
    3196                 :            : 
    3197                 :            : static PyObject *
    3198                 :      47647 : MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    3199                 :            : {
    3200                 :            :     PyBaseExceptionObject *self;
    3201                 :            : 
    3202                 :            :     /* If this is a subclass of MemoryError, don't use the freelist
    3203                 :            :      * and just return a fresh object */
    3204         [ +  + ]:      47647 :     if (type != (PyTypeObject *) PyExc_MemoryError) {
    3205                 :          1 :         return BaseException_new(type, args, kwds);
    3206                 :            :     }
    3207                 :            : 
    3208                 :      47646 :     struct _Py_exc_state *state = get_exc_state();
    3209         [ +  + ]:      47646 :     if (state->memerrors_freelist == NULL) {
    3210                 :      47475 :         return BaseException_new(type, args, kwds);
    3211                 :            :     }
    3212                 :            : 
    3213                 :            :     /* Fetch object from freelist and revive it */
    3214                 :        171 :     self = state->memerrors_freelist;
    3215                 :        171 :     self->args = PyTuple_New(0);
    3216                 :            :     /* This shouldn't happen since the empty tuple is persistent */
    3217         [ -  + ]:        171 :     if (self->args == NULL) {
    3218                 :          0 :         return NULL;
    3219                 :            :     }
    3220                 :            : 
    3221                 :        171 :     state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
    3222                 :        171 :     state->memerrors_numfree--;
    3223                 :        171 :     self->dict = NULL;
    3224                 :        171 :     _Py_NewReference((PyObject *)self);
    3225                 :        171 :     _PyObject_GC_TRACK(self);
    3226                 :        171 :     return (PyObject *)self;
    3227                 :            : }
    3228                 :            : 
    3229                 :            : static void
    3230                 :      47647 : MemoryError_dealloc(PyBaseExceptionObject *self)
    3231                 :            : {
    3232                 :      47647 :     BaseException_clear(self);
    3233                 :            : 
    3234                 :            :     /* If this is a subclass of MemoryError, we don't need to
    3235                 :            :      * do anything in the free-list*/
    3236         [ +  + ]:      47647 :     if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
    3237                 :          1 :         Py_TYPE(self)->tp_free((PyObject *)self);
    3238                 :          1 :         return;
    3239                 :            :     }
    3240                 :            : 
    3241                 :      47646 :     _PyObject_GC_UNTRACK(self);
    3242                 :            : 
    3243                 :      47646 :     struct _Py_exc_state *state = get_exc_state();
    3244         [ +  + ]:      47646 :     if (state->memerrors_numfree >= MEMERRORS_SAVE) {
    3245                 :          3 :         Py_TYPE(self)->tp_free((PyObject *)self);
    3246                 :            :     }
    3247                 :            :     else {
    3248                 :      47643 :         self->dict = (PyObject *) state->memerrors_freelist;
    3249                 :      47643 :         state->memerrors_freelist = self;
    3250                 :      47643 :         state->memerrors_numfree++;
    3251                 :            :     }
    3252                 :            : }
    3253                 :            : 
    3254                 :            : static int
    3255                 :       2967 : preallocate_memerrors(void)
    3256                 :            : {
    3257                 :            :     /* We create enough MemoryErrors and then decref them, which will fill
    3258                 :            :        up the freelist. */
    3259                 :            :     int i;
    3260                 :            :     PyObject *errors[MEMERRORS_SAVE];
    3261         [ +  + ]:      50439 :     for (i = 0; i < MEMERRORS_SAVE; i++) {
    3262                 :      47472 :         errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
    3263                 :            :                                     NULL, NULL);
    3264         [ -  + ]:      47472 :         if (!errors[i]) {
    3265                 :          0 :             return -1;
    3266                 :            :         }
    3267                 :            :     }
    3268         [ +  + ]:      50439 :     for (i = 0; i < MEMERRORS_SAVE; i++) {
    3269                 :      47472 :         Py_DECREF(errors[i]);
    3270                 :            :     }
    3271                 :       2967 :     return 0;
    3272                 :            : }
    3273                 :            : 
    3274                 :            : static void
    3275                 :       3125 : free_preallocated_memerrors(struct _Py_exc_state *state)
    3276                 :            : {
    3277         [ +  + ]:      50421 :     while (state->memerrors_freelist != NULL) {
    3278                 :      47296 :         PyObject *self = (PyObject *) state->memerrors_freelist;
    3279                 :      47296 :         state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
    3280                 :      47296 :         Py_TYPE(self)->tp_free((PyObject *)self);
    3281                 :            :     }
    3282                 :       3125 : }
    3283                 :            : 
    3284                 :            : 
    3285                 :            : static PyTypeObject _PyExc_MemoryError = {
    3286                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
    3287                 :            :     "MemoryError",
    3288                 :            :     sizeof(PyBaseExceptionObject),
    3289                 :            :     0, (destructor)MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
    3290                 :            :     0, 0, 0, 0, 0, 0, 0,
    3291                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    3292                 :            :     PyDoc_STR("Out of memory."), (traverseproc)BaseException_traverse,
    3293                 :            :     (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
    3294                 :            :     0, 0, 0, offsetof(PyBaseExceptionObject, dict),
    3295                 :            :     (initproc)BaseException_init, 0, MemoryError_new
    3296                 :            : };
    3297                 :            : PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
    3298                 :            : 
    3299                 :            : 
    3300                 :            : /*
    3301                 :            :  *    BufferError extends Exception
    3302                 :            :  */
    3303                 :            : SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
    3304                 :            : 
    3305                 :            : 
    3306                 :            : /* Warning category docstrings */
    3307                 :            : 
    3308                 :            : /*
    3309                 :            :  *    Warning extends Exception
    3310                 :            :  */
    3311                 :            : SimpleExtendsException(PyExc_Exception, Warning,
    3312                 :            :                        "Base class for warning categories.");
    3313                 :            : 
    3314                 :            : 
    3315                 :            : /*
    3316                 :            :  *    UserWarning extends Warning
    3317                 :            :  */
    3318                 :            : SimpleExtendsException(PyExc_Warning, UserWarning,
    3319                 :            :                        "Base class for warnings generated by user code.");
    3320                 :            : 
    3321                 :            : 
    3322                 :            : /*
    3323                 :            :  *    DeprecationWarning extends Warning
    3324                 :            :  */
    3325                 :            : SimpleExtendsException(PyExc_Warning, DeprecationWarning,
    3326                 :            :                        "Base class for warnings about deprecated features.");
    3327                 :            : 
    3328                 :            : 
    3329                 :            : /*
    3330                 :            :  *    PendingDeprecationWarning extends Warning
    3331                 :            :  */
    3332                 :            : SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
    3333                 :            :     "Base class for warnings about features which will be deprecated\n"
    3334                 :            :     "in the future.");
    3335                 :            : 
    3336                 :            : 
    3337                 :            : /*
    3338                 :            :  *    SyntaxWarning extends Warning
    3339                 :            :  */
    3340                 :            : SimpleExtendsException(PyExc_Warning, SyntaxWarning,
    3341                 :            :                        "Base class for warnings about dubious syntax.");
    3342                 :            : 
    3343                 :            : 
    3344                 :            : /*
    3345                 :            :  *    RuntimeWarning extends Warning
    3346                 :            :  */
    3347                 :            : SimpleExtendsException(PyExc_Warning, RuntimeWarning,
    3348                 :            :                  "Base class for warnings about dubious runtime behavior.");
    3349                 :            : 
    3350                 :            : 
    3351                 :            : /*
    3352                 :            :  *    FutureWarning extends Warning
    3353                 :            :  */
    3354                 :            : SimpleExtendsException(PyExc_Warning, FutureWarning,
    3355                 :            :     "Base class for warnings about constructs that will change semantically\n"
    3356                 :            :     "in the future.");
    3357                 :            : 
    3358                 :            : 
    3359                 :            : /*
    3360                 :            :  *    ImportWarning extends Warning
    3361                 :            :  */
    3362                 :            : SimpleExtendsException(PyExc_Warning, ImportWarning,
    3363                 :            :           "Base class for warnings about probable mistakes in module imports");
    3364                 :            : 
    3365                 :            : 
    3366                 :            : /*
    3367                 :            :  *    UnicodeWarning extends Warning
    3368                 :            :  */
    3369                 :            : SimpleExtendsException(PyExc_Warning, UnicodeWarning,
    3370                 :            :     "Base class for warnings about Unicode related problems, mostly\n"
    3371                 :            :     "related to conversion problems.");
    3372                 :            : 
    3373                 :            : 
    3374                 :            : /*
    3375                 :            :  *    BytesWarning extends Warning
    3376                 :            :  */
    3377                 :            : SimpleExtendsException(PyExc_Warning, BytesWarning,
    3378                 :            :     "Base class for warnings about bytes and buffer related problems, mostly\n"
    3379                 :            :     "related to conversion from str or comparing to str.");
    3380                 :            : 
    3381                 :            : 
    3382                 :            : /*
    3383                 :            :  *    EncodingWarning extends Warning
    3384                 :            :  */
    3385                 :            : SimpleExtendsException(PyExc_Warning, EncodingWarning,
    3386                 :            :     "Base class for warnings about encodings.");
    3387                 :            : 
    3388                 :            : 
    3389                 :            : /*
    3390                 :            :  *    ResourceWarning extends Warning
    3391                 :            :  */
    3392                 :            : SimpleExtendsException(PyExc_Warning, ResourceWarning,
    3393                 :            :     "Base class for warnings about resource usage.");
    3394                 :            : 
    3395                 :            : 
    3396                 :            : 
    3397                 :            : #ifdef MS_WINDOWS
    3398                 :            : #include <winsock2.h>
    3399                 :            : /* The following constants were added to errno.h in VS2010 but have
    3400                 :            :    preferred WSA equivalents. */
    3401                 :            : #undef EADDRINUSE
    3402                 :            : #undef EADDRNOTAVAIL
    3403                 :            : #undef EAFNOSUPPORT
    3404                 :            : #undef EALREADY
    3405                 :            : #undef ECONNABORTED
    3406                 :            : #undef ECONNREFUSED
    3407                 :            : #undef ECONNRESET
    3408                 :            : #undef EDESTADDRREQ
    3409                 :            : #undef EHOSTUNREACH
    3410                 :            : #undef EINPROGRESS
    3411                 :            : #undef EISCONN
    3412                 :            : #undef ELOOP
    3413                 :            : #undef EMSGSIZE
    3414                 :            : #undef ENETDOWN
    3415                 :            : #undef ENETRESET
    3416                 :            : #undef ENETUNREACH
    3417                 :            : #undef ENOBUFS
    3418                 :            : #undef ENOPROTOOPT
    3419                 :            : #undef ENOTCONN
    3420                 :            : #undef ENOTSOCK
    3421                 :            : #undef EOPNOTSUPP
    3422                 :            : #undef EPROTONOSUPPORT
    3423                 :            : #undef EPROTOTYPE
    3424                 :            : #undef ETIMEDOUT
    3425                 :            : #undef EWOULDBLOCK
    3426                 :            : 
    3427                 :            : #if defined(WSAEALREADY) && !defined(EALREADY)
    3428                 :            : #define EALREADY WSAEALREADY
    3429                 :            : #endif
    3430                 :            : #if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
    3431                 :            : #define ECONNABORTED WSAECONNABORTED
    3432                 :            : #endif
    3433                 :            : #if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
    3434                 :            : #define ECONNREFUSED WSAECONNREFUSED
    3435                 :            : #endif
    3436                 :            : #if defined(WSAECONNRESET) && !defined(ECONNRESET)
    3437                 :            : #define ECONNRESET WSAECONNRESET
    3438                 :            : #endif
    3439                 :            : #if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
    3440                 :            : #define EINPROGRESS WSAEINPROGRESS
    3441                 :            : #endif
    3442                 :            : #if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
    3443                 :            : #define ESHUTDOWN WSAESHUTDOWN
    3444                 :            : #endif
    3445                 :            : #if defined(WSAETIMEDOUT) && !defined(ETIMEDOUT)
    3446                 :            : #define ETIMEDOUT WSAETIMEDOUT
    3447                 :            : #endif
    3448                 :            : #if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
    3449                 :            : #define EWOULDBLOCK WSAEWOULDBLOCK
    3450                 :            : #endif
    3451                 :            : #endif /* MS_WINDOWS */
    3452                 :            : 
    3453                 :            : struct static_exception {
    3454                 :            :     PyTypeObject *exc;
    3455                 :            :     const char *name;
    3456                 :            : };
    3457                 :            : 
    3458                 :            : static struct static_exception static_exceptions[] = {
    3459                 :            : #define ITEM(NAME) {&_PyExc_##NAME, #NAME}
    3460                 :            :     // Level 1
    3461                 :            :     ITEM(BaseException),
    3462                 :            : 
    3463                 :            :     // Level 2: BaseException subclasses
    3464                 :            :     ITEM(BaseExceptionGroup),
    3465                 :            :     ITEM(Exception),
    3466                 :            :     ITEM(GeneratorExit),
    3467                 :            :     ITEM(KeyboardInterrupt),
    3468                 :            :     ITEM(SystemExit),
    3469                 :            : 
    3470                 :            :     // Level 3: Exception(BaseException) subclasses
    3471                 :            :     ITEM(ArithmeticError),
    3472                 :            :     ITEM(AssertionError),
    3473                 :            :     ITEM(AttributeError),
    3474                 :            :     ITEM(BufferError),
    3475                 :            :     ITEM(EOFError),
    3476                 :            :     //ITEM(ExceptionGroup),
    3477                 :            :     ITEM(ImportError),
    3478                 :            :     ITEM(LookupError),
    3479                 :            :     ITEM(MemoryError),
    3480                 :            :     ITEM(NameError),
    3481                 :            :     ITEM(OSError),
    3482                 :            :     ITEM(ReferenceError),
    3483                 :            :     ITEM(RuntimeError),
    3484                 :            :     ITEM(StopAsyncIteration),
    3485                 :            :     ITEM(StopIteration),
    3486                 :            :     ITEM(SyntaxError),
    3487                 :            :     ITEM(SystemError),
    3488                 :            :     ITEM(TypeError),
    3489                 :            :     ITEM(ValueError),
    3490                 :            :     ITEM(Warning),
    3491                 :            : 
    3492                 :            :     // Level 4: ArithmeticError(Exception) subclasses
    3493                 :            :     ITEM(FloatingPointError),
    3494                 :            :     ITEM(OverflowError),
    3495                 :            :     ITEM(ZeroDivisionError),
    3496                 :            : 
    3497                 :            :     // Level 4: Warning(Exception) subclasses
    3498                 :            :     ITEM(BytesWarning),
    3499                 :            :     ITEM(DeprecationWarning),
    3500                 :            :     ITEM(EncodingWarning),
    3501                 :            :     ITEM(FutureWarning),
    3502                 :            :     ITEM(ImportWarning),
    3503                 :            :     ITEM(PendingDeprecationWarning),
    3504                 :            :     ITEM(ResourceWarning),
    3505                 :            :     ITEM(RuntimeWarning),
    3506                 :            :     ITEM(SyntaxWarning),
    3507                 :            :     ITEM(UnicodeWarning),
    3508                 :            :     ITEM(UserWarning),
    3509                 :            : 
    3510                 :            :     // Level 4: OSError(Exception) subclasses
    3511                 :            :     ITEM(BlockingIOError),
    3512                 :            :     ITEM(ChildProcessError),
    3513                 :            :     ITEM(ConnectionError),
    3514                 :            :     ITEM(FileExistsError),
    3515                 :            :     ITEM(FileNotFoundError),
    3516                 :            :     ITEM(InterruptedError),
    3517                 :            :     ITEM(IsADirectoryError),
    3518                 :            :     ITEM(NotADirectoryError),
    3519                 :            :     ITEM(PermissionError),
    3520                 :            :     ITEM(ProcessLookupError),
    3521                 :            :     ITEM(TimeoutError),
    3522                 :            : 
    3523                 :            :     // Level 4: Other subclasses
    3524                 :            :     ITEM(IndentationError), // base: SyntaxError(Exception)
    3525                 :            :     ITEM(IndexError),  // base: LookupError(Exception)
    3526                 :            :     ITEM(KeyError),  // base: LookupError(Exception)
    3527                 :            :     ITEM(ModuleNotFoundError), // base: ImportError(Exception)
    3528                 :            :     ITEM(NotImplementedError),  // base: RuntimeError(Exception)
    3529                 :            :     ITEM(RecursionError),  // base: RuntimeError(Exception)
    3530                 :            :     ITEM(UnboundLocalError), // base: NameError(Exception)
    3531                 :            :     ITEM(UnicodeError),  // base: ValueError(Exception)
    3532                 :            : 
    3533                 :            :     // Level 5: ConnectionError(OSError) subclasses
    3534                 :            :     ITEM(BrokenPipeError),
    3535                 :            :     ITEM(ConnectionAbortedError),
    3536                 :            :     ITEM(ConnectionRefusedError),
    3537                 :            :     ITEM(ConnectionResetError),
    3538                 :            : 
    3539                 :            :     // Level 5: IndentationError(SyntaxError) subclasses
    3540                 :            :     ITEM(TabError),  // base: IndentationError
    3541                 :            : 
    3542                 :            :     // Level 5: UnicodeError(ValueError) subclasses
    3543                 :            :     ITEM(UnicodeDecodeError),
    3544                 :            :     ITEM(UnicodeEncodeError),
    3545                 :            :     ITEM(UnicodeTranslateError),
    3546                 :            : #undef ITEM
    3547                 :            : };
    3548                 :            : 
    3549                 :            : 
    3550                 :            : int
    3551                 :       3138 : _PyExc_InitTypes(PyInterpreterState *interp)
    3552                 :            : {
    3553         [ +  + ]:       3138 :     if (!_Py_IsMainInterpreter(interp)) {
    3554                 :        171 :         return 0;
    3555                 :            :     }
    3556                 :            : 
    3557         [ +  + ]:     198789 :     for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
    3558                 :     195822 :         PyTypeObject *exc = static_exceptions[i].exc;
    3559                 :            : 
    3560         [ -  + ]:     195822 :         if (PyType_Ready(exc) < 0) {
    3561                 :          0 :             return -1;
    3562                 :            :         }
    3563                 :            :     }
    3564                 :       2967 :     return 0;
    3565                 :            : }
    3566                 :            : 
    3567                 :            : 
    3568                 :            : static void
    3569                 :       3125 : _PyExc_FiniTypes(PyInterpreterState *interp)
    3570                 :            : {
    3571         [ +  + ]:       3125 :     if (!_Py_IsMainInterpreter(interp)) {
    3572                 :        169 :         return;
    3573                 :            :     }
    3574                 :            : 
    3575         [ +  + ]:     198052 :     for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
    3576                 :     195096 :         PyTypeObject *exc = static_exceptions[i].exc;
    3577                 :     195096 :         _PyStaticType_Dealloc(exc);
    3578                 :            :     }
    3579                 :            : }
    3580                 :            : 
    3581                 :            : 
    3582                 :            : PyStatus
    3583                 :       3138 : _PyExc_InitGlobalObjects(PyInterpreterState *interp)
    3584                 :            : {
    3585         [ +  + ]:       3138 :     if (!_Py_IsMainInterpreter(interp)) {
    3586                 :        171 :         return _PyStatus_OK();
    3587                 :            :     }
    3588                 :            : 
    3589         [ -  + ]:       2967 :     if (preallocate_memerrors() < 0) {
    3590                 :          0 :         return _PyStatus_NO_MEMORY();
    3591                 :            :     }
    3592                 :       2967 :     return _PyStatus_OK();
    3593                 :            : }
    3594                 :            : 
    3595                 :            : PyStatus
    3596                 :       3138 : _PyExc_InitState(PyInterpreterState *interp)
    3597                 :            : {
    3598                 :       3138 :     struct _Py_exc_state *state = &interp->exc_state;
    3599                 :            : 
    3600                 :            : #define ADD_ERRNO(TYPE, CODE) \
    3601                 :            :     do { \
    3602                 :            :         PyObject *_code = PyLong_FromLong(CODE); \
    3603                 :            :         assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
    3604                 :            :         if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
    3605                 :            :             Py_XDECREF(_code); \
    3606                 :            :             return _PyStatus_ERR("errmap insertion problem."); \
    3607                 :            :         } \
    3608                 :            :         Py_DECREF(_code); \
    3609                 :            :     } while (0)
    3610                 :            : 
    3611                 :            :     /* Add exceptions to errnomap */
    3612                 :            :     assert(state->errnomap == NULL);
    3613                 :       3138 :     state->errnomap = PyDict_New();
    3614         [ -  + ]:       3138 :     if (!state->errnomap) {
    3615                 :          0 :         return _PyStatus_NO_MEMORY();
    3616                 :            :     }
    3617                 :            : 
    3618   [ +  -  -  + ]:       3138 :     ADD_ERRNO(BlockingIOError, EAGAIN);
    3619   [ +  -  -  + ]:       3138 :     ADD_ERRNO(BlockingIOError, EALREADY);
    3620   [ +  -  -  + ]:       3138 :     ADD_ERRNO(BlockingIOError, EINPROGRESS);
    3621   [ +  -  -  + ]:       3138 :     ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
    3622   [ +  -  -  + ]:       3138 :     ADD_ERRNO(BrokenPipeError, EPIPE);
    3623                 :            : #ifdef ESHUTDOWN
    3624   [ +  -  -  + ]:       3138 :     ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
    3625                 :            : #endif
    3626   [ +  -  -  + ]:       3138 :     ADD_ERRNO(ChildProcessError, ECHILD);
    3627   [ +  -  -  + ]:       3138 :     ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
    3628   [ +  -  -  + ]:       3138 :     ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
    3629   [ +  -  -  + ]:       3138 :     ADD_ERRNO(ConnectionResetError, ECONNRESET);
    3630   [ +  -  -  + ]:       3138 :     ADD_ERRNO(FileExistsError, EEXIST);
    3631   [ +  -  -  + ]:       3138 :     ADD_ERRNO(FileNotFoundError, ENOENT);
    3632   [ +  -  -  + ]:       3138 :     ADD_ERRNO(IsADirectoryError, EISDIR);
    3633   [ +  -  -  + ]:       3138 :     ADD_ERRNO(NotADirectoryError, ENOTDIR);
    3634   [ +  -  -  + ]:       3138 :     ADD_ERRNO(InterruptedError, EINTR);
    3635   [ +  -  -  + ]:       3138 :     ADD_ERRNO(PermissionError, EACCES);
    3636   [ +  -  -  + ]:       3138 :     ADD_ERRNO(PermissionError, EPERM);
    3637   [ +  -  -  + ]:       3138 :     ADD_ERRNO(ProcessLookupError, ESRCH);
    3638   [ +  -  -  + ]:       3138 :     ADD_ERRNO(TimeoutError, ETIMEDOUT);
    3639                 :            : 
    3640                 :       3138 :     return _PyStatus_OK();
    3641                 :            : 
    3642                 :            : #undef ADD_ERRNO
    3643                 :            : }
    3644                 :            : 
    3645                 :            : 
    3646                 :            : /* Add exception types to the builtins module */
    3647                 :            : int
    3648                 :       3138 : _PyBuiltins_AddExceptions(PyObject *bltinmod)
    3649                 :            : {
    3650                 :       3138 :     PyObject *mod_dict = PyModule_GetDict(bltinmod);
    3651         [ -  + ]:       3138 :     if (mod_dict == NULL) {
    3652                 :          0 :         return -1;
    3653                 :            :     }
    3654                 :            : 
    3655         [ +  + ]:     210246 :     for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
    3656                 :     207108 :         struct static_exception item = static_exceptions[i];
    3657                 :            : 
    3658         [ -  + ]:     207108 :         if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
    3659                 :          0 :             return -1;
    3660                 :            :         }
    3661                 :            :     }
    3662                 :            : 
    3663                 :       3138 :     PyObject *PyExc_ExceptionGroup = create_exception_group_class();
    3664         [ -  + ]:       3138 :     if (!PyExc_ExceptionGroup) {
    3665                 :          0 :         return -1;
    3666                 :            :     }
    3667         [ -  + ]:       3138 :     if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
    3668                 :          0 :         return -1;
    3669                 :            :     }
    3670                 :            : 
    3671                 :            : #define INIT_ALIAS(NAME, TYPE) \
    3672                 :            :     do { \
    3673                 :            :         PyExc_ ## NAME = PyExc_ ## TYPE; \
    3674                 :            :         if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## TYPE)) { \
    3675                 :            :             return -1; \
    3676                 :            :         } \
    3677                 :            :     } while (0)
    3678                 :            : 
    3679         [ -  + ]:       3138 :     INIT_ALIAS(EnvironmentError, OSError);
    3680         [ -  + ]:       3138 :     INIT_ALIAS(IOError, OSError);
    3681                 :            : #ifdef MS_WINDOWS
    3682                 :            :     INIT_ALIAS(WindowsError, OSError);
    3683                 :            : #endif
    3684                 :            : 
    3685                 :            : #undef INIT_ALIAS
    3686                 :            : 
    3687                 :       3138 :     return 0;
    3688                 :            : }
    3689                 :            : 
    3690                 :            : void
    3691                 :       3125 : _PyExc_ClearExceptionGroupType(PyInterpreterState *interp)
    3692                 :            : {
    3693                 :       3125 :     struct _Py_exc_state *state = &interp->exc_state;
    3694         [ +  - ]:       3125 :     Py_CLEAR(state->PyExc_ExceptionGroup);
    3695                 :       3125 : }
    3696                 :            : 
    3697                 :            : void
    3698                 :       3125 : _PyExc_Fini(PyInterpreterState *interp)
    3699                 :            : {
    3700                 :       3125 :     struct _Py_exc_state *state = &interp->exc_state;
    3701                 :       3125 :     free_preallocated_memerrors(state);
    3702         [ +  - ]:       3125 :     Py_CLEAR(state->errnomap);
    3703                 :            : 
    3704                 :       3125 :     _PyExc_FiniTypes(interp);
    3705                 :       3125 : }
    3706                 :            : 
    3707                 :            : /* Helper to do the equivalent of "raise X from Y" in C, but always using
    3708                 :            :  * the current exception rather than passing one in.
    3709                 :            :  *
    3710                 :            :  * We currently limit this to *only* exceptions that use the BaseException
    3711                 :            :  * tp_init and tp_new methods, since we can be reasonably sure we can wrap
    3712                 :            :  * those correctly without losing data and without losing backwards
    3713                 :            :  * compatibility.
    3714                 :            :  *
    3715                 :            :  * We also aim to rule out *all* exceptions that might be storing additional
    3716                 :            :  * state, whether by having a size difference relative to BaseException,
    3717                 :            :  * additional arguments passed in during construction or by having a
    3718                 :            :  * non-empty instance dict.
    3719                 :            :  *
    3720                 :            :  * We need to be very careful with what we wrap, since changing types to
    3721                 :            :  * a broader exception type would be backwards incompatible for
    3722                 :            :  * existing codecs, and with different init or new method implementations
    3723                 :            :  * may either not support instantiation with PyErr_Format or lose
    3724                 :            :  * information when instantiated that way.
    3725                 :            :  *
    3726                 :            :  * XXX (ncoghlan): This could be made more comprehensive by exploiting the
    3727                 :            :  * fact that exceptions are expected to support pickling. If more builtin
    3728                 :            :  * exceptions (e.g. AttributeError) start to be converted to rich
    3729                 :            :  * exceptions with additional attributes, that's probably a better approach
    3730                 :            :  * to pursue over adding special cases for particular stateful subclasses.
    3731                 :            :  *
    3732                 :            :  * Returns a borrowed reference to the new exception (if any), NULL if the
    3733                 :            :  * existing exception was left in place.
    3734                 :            :  */
    3735                 :            : PyObject *
    3736                 :        141 : _PyErr_TrySetFromCause(const char *format, ...)
    3737                 :            : {
    3738                 :            :     PyObject* msg_prefix;
    3739                 :            :     PyObject *exc, *val, *tb;
    3740                 :            :     PyTypeObject *caught_type;
    3741                 :            :     PyObject *instance_args;
    3742                 :            :     Py_ssize_t num_args, caught_type_size, base_exc_size;
    3743                 :            :     PyObject *new_exc, *new_val, *new_tb;
    3744                 :            :     va_list vargs;
    3745                 :            :     int same_basic_size;
    3746                 :            : 
    3747                 :        141 :     PyErr_Fetch(&exc, &val, &tb);
    3748                 :        141 :     caught_type = (PyTypeObject *)exc;
    3749                 :            :     /* Ensure type info indicates no extra state is stored at the C level
    3750                 :            :      * and that the type can be reinstantiated using PyErr_Format
    3751                 :            :      */
    3752                 :        141 :     caught_type_size = caught_type->tp_basicsize;
    3753                 :        141 :     base_exc_size = _PyExc_BaseException.tp_basicsize;
    3754                 :        141 :     same_basic_size = (
    3755   [ +  +  +  + ]:        221 :         caught_type_size == base_exc_size ||
    3756                 :         66 :         (_PyType_SUPPORTS_WEAKREFS(caught_type) &&
    3757         [ +  - ]:         14 :             (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *))
    3758                 :            :         )
    3759                 :            :     );
    3760         [ +  + ]:        141 :     if (caught_type->tp_init != (initproc)BaseException_init ||
    3761   [ +  +  +  - ]:         85 :         caught_type->tp_new != BaseException_new ||
    3762                 :         81 :         !same_basic_size ||
    3763         [ -  + ]:         81 :         caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) {
    3764                 :            :         /* We can't be sure we can wrap this safely, since it may contain
    3765                 :            :          * more state than just the exception type. Accordingly, we just
    3766                 :            :          * leave it alone.
    3767                 :            :          */
    3768                 :         60 :         PyErr_Restore(exc, val, tb);
    3769                 :         60 :         return NULL;
    3770                 :            :     }
    3771                 :            : 
    3772                 :            :     /* Check the args are empty or contain a single string */
    3773                 :         81 :     PyErr_NormalizeException(&exc, &val, &tb);
    3774                 :         81 :     instance_args = ((PyBaseExceptionObject *)val)->args;
    3775                 :         81 :     num_args = PyTuple_GET_SIZE(instance_args);
    3776   [ +  +  +  + ]:         81 :     if (num_args > 1 ||
    3777         [ +  + ]:         73 :         (num_args == 1 &&
    3778                 :         73 :          !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) {
    3779                 :            :         /* More than 1 arg, or the one arg we do have isn't a string
    3780                 :            :          */
    3781                 :          8 :         PyErr_Restore(exc, val, tb);
    3782                 :          8 :         return NULL;
    3783                 :            :     }
    3784                 :            : 
    3785                 :            :     /* Ensure the instance dict is also empty */
    3786         [ +  + ]:         73 :     if (!_PyObject_IsInstanceDictEmpty(val)) {
    3787                 :            :         /* While we could potentially copy a non-empty instance dictionary
    3788                 :            :          * to the replacement exception, for now we take the more
    3789                 :            :          * conservative path of leaving exceptions with attributes set
    3790                 :            :          * alone.
    3791                 :            :          */
    3792                 :          4 :         PyErr_Restore(exc, val, tb);
    3793                 :          4 :         return NULL;
    3794                 :            :     }
    3795                 :            : 
    3796                 :            :     /* For exceptions that we can wrap safely, we chain the original
    3797                 :            :      * exception to a new one of the exact same type with an
    3798                 :            :      * error message that mentions the additional details and the
    3799                 :            :      * original exception.
    3800                 :            :      *
    3801                 :            :      * It would be nice to wrap OSError and various other exception
    3802                 :            :      * types as well, but that's quite a bit trickier due to the extra
    3803                 :            :      * state potentially stored on OSError instances.
    3804                 :            :      */
    3805                 :            :     /* Ensure the traceback is set correctly on the existing exception */
    3806         [ +  + ]:         69 :     if (tb != NULL) {
    3807                 :         62 :         PyException_SetTraceback(val, tb);
    3808                 :         62 :         Py_DECREF(tb);
    3809                 :            :     }
    3810                 :            : 
    3811                 :         69 :     va_start(vargs, format);
    3812                 :         69 :     msg_prefix = PyUnicode_FromFormatV(format, vargs);
    3813                 :         69 :     va_end(vargs);
    3814         [ -  + ]:         69 :     if (msg_prefix == NULL) {
    3815                 :          0 :         Py_DECREF(exc);
    3816                 :          0 :         Py_DECREF(val);
    3817                 :          0 :         return NULL;
    3818                 :            :     }
    3819                 :            : 
    3820                 :         69 :     PyErr_Format(exc, "%U (%s: %S)",
    3821                 :         69 :                  msg_prefix, Py_TYPE(val)->tp_name, val);
    3822                 :         69 :     Py_DECREF(exc);
    3823                 :         69 :     Py_DECREF(msg_prefix);
    3824                 :         69 :     PyErr_Fetch(&new_exc, &new_val, &new_tb);
    3825                 :         69 :     PyErr_NormalizeException(&new_exc, &new_val, &new_tb);
    3826                 :         69 :     PyException_SetCause(new_val, val);
    3827                 :         69 :     PyErr_Restore(new_exc, new_val, new_tb);
    3828                 :         69 :     return new_val;
    3829                 :            : }

Generated by: LCOV version 1.14