LCOV - code coverage report
Current view: top level - Objects - exceptions.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 368 1403 26.2 %
Date: 2023-03-20 08:15:36 Functions: 57 144 39.6 %
Branches: 170 989 17.2 %

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

Generated by: LCOV version 1.14