LCOV - code coverage report
Current view: top level - Objects - exceptions.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 1245 1424 87.4 %
Date: 2022-07-07 18:19:46 Functions: 131 139 94.2 %

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

Generated by: LCOV version 1.14