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