/*
 * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
 *
 * Thanks go to Tim Peters and Michael Hudson for debugging.
 */

#include <Python.h>
#include <stdbool.h>
#include "pycore_abstract.h"      // _PyObject_RealIsSubclass()
#include "pycore_ceval.h"         // _Py_EnterRecursiveCall
#include "pycore_exceptions.h"    // struct _Py_exc_state
#include "pycore_initconfig.h"
#include "pycore_modsupport.h"    // _PyArg_NoKeywords()
#include "pycore_object.h"
#include "pycore_pyerrors.h"      // struct _PyErr_SetRaisedException
#include "pycore_tuple.h"         // _PyTuple_FromPair

#include "osdefs.h"               // SEP
#include "clinic/exceptions.c.h"


/*[clinic input]
class BaseException "PyBaseExceptionObject *" "&PyExc_BaseException"
class BaseExceptionGroup "PyBaseExceptionGroupObject *" "&PyExc_BaseExceptionGroup"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b7c45e78cff8edc3]*/


static struct _Py_exc_state*
get_exc_state(void)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    return &interp->exc_state;
}


/* NOTE: If the exception class hierarchy changes, don't forget to update
 * Lib/test/exception_hierarchy.txt
 */

static inline PyBaseExceptionObject *
PyBaseExceptionObject_CAST(PyObject *exc)
{
    assert(PyExceptionInstance_Check(exc));
    return (PyBaseExceptionObject *)exc;
}

/*
 *    BaseException
 */
static PyObject *
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyBaseExceptionObject *self;

    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
    if (!self)
        return NULL;
    /* the dict is created on the fly in PyObject_GenericSetAttr */
    self->dict = NULL;
    self->notes = NULL;
    self->traceback = self->cause = self->context = NULL;
    self->suppress_context = 0;

    if (args) {
        self->args = Py_NewRef(args);
        return (PyObject *)self;
    }

    self->args = PyTuple_New(0);
    if (!self->args) {
        Py_DECREF(self);
        return NULL;
    }

    return (PyObject *)self;
}

static int
BaseException_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
        return -1;

    Py_XSETREF(self->args, Py_NewRef(args));
    return 0;
}


static PyObject *
BaseException_vectorcall(PyObject *type_obj, PyObject * const*args,
                         size_t nargsf, PyObject *kwnames)
{
    PyTypeObject *type = _PyType_CAST(type_obj);
    if (!_PyArg_NoKwnames(type->tp_name, kwnames)) {
        return NULL;
    }

    PyBaseExceptionObject *self;
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
    if (!self) {
        return NULL;
    }

    // The dict is created on the fly in PyObject_GenericSetAttr()
    self->dict = NULL;
    self->notes = NULL;
    self->traceback = NULL;
    self->cause = NULL;
    self->context = NULL;
    self->suppress_context = 0;

    self->args = PyTuple_FromArray(args, PyVectorcall_NARGS(nargsf));
    if (!self->args) {
        Py_DECREF(self);
        return NULL;
    }

    return (PyObject *)self;
}


static int
BaseException_clear(PyObject *op)
{
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
    Py_CLEAR(self->dict);
    Py_CLEAR(self->args);
    Py_CLEAR(self->notes);
    Py_CLEAR(self->traceback);
    Py_CLEAR(self->cause);
    Py_CLEAR(self->context);
    return 0;
}

static void
BaseException_dealloc(PyObject *op)
{
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
    PyObject_GC_UnTrack(self);
    // bpo-44348: The trashcan mechanism prevents stack overflow when deleting
    // long chains of exceptions. For example, exceptions can be chained
    // through the __context__ attributes or the __traceback__ attribute.
    (void)BaseException_clear(op);
    Py_TYPE(self)->tp_free(self);
}

static int
BaseException_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
    Py_VISIT(self->dict);
    Py_VISIT(self->args);
    Py_VISIT(self->notes);
    Py_VISIT(self->traceback);
    Py_VISIT(self->cause);
    Py_VISIT(self->context);
    return 0;
}

static PyObject *
BaseException_str(PyObject *op)
{
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);

    PyObject *res;
    Py_BEGIN_CRITICAL_SECTION(self);
    switch (PyTuple_GET_SIZE(self->args)) {
    case 0:
        res = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
        break;
    case 1:
        res = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
        break;
    default:
        res = PyObject_Str(self->args);
        break;
    }
    Py_END_CRITICAL_SECTION();
    return res;
}

static PyObject *
BaseException_repr(PyObject *op)
{

    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);

    PyObject *res;
    Py_BEGIN_CRITICAL_SECTION(self);
    const char *name = _PyType_Name(Py_TYPE(self));
    if (PyTuple_GET_SIZE(self->args) == 1) {
        res = PyUnicode_FromFormat("%s(%R)", name,
                                    PyTuple_GET_ITEM(self->args, 0));
    }
    else {
        res = PyUnicode_FromFormat("%s%R", name, self->args);
    }
    Py_END_CRITICAL_SECTION();
    return res;
}

/* Pickling support */

/*[clinic input]
@critical_section
BaseException.__reduce__
[clinic start generated code]*/

static PyObject *
BaseException___reduce___impl(PyBaseExceptionObject *self)
/*[clinic end generated code: output=af87c1247ef98748 input=283be5a10d9c964f]*/
{
    if (self->args && self->dict)
        return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
    else
        return _PyTuple_FromPair((PyObject *)Py_TYPE(self), self->args);
}

/*
 * Needed for backward compatibility, since exceptions used to store
 * all their attributes in the __dict__. Code is taken from cPickle's
 * load_build function.
 */

/*[clinic input]
@critical_section
BaseException.__setstate__
    state: object
    /
[clinic start generated code]*/

static PyObject *
BaseException___setstate___impl(PyBaseExceptionObject *self, PyObject *state)
/*[clinic end generated code: output=f3834889950453ab input=5524b61cfe9b9856]*/
{
    PyObject *d_key, *d_value;
    Py_ssize_t i = 0;

    if (state != Py_None) {
        if (!PyDict_Check(state)) {
            PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
            return NULL;
        }
        while (PyDict_Next(state, &i, &d_key, &d_value)) {
            Py_INCREF(d_key);
            Py_INCREF(d_value);
            int res = PyObject_SetAttr((PyObject *)self, d_key, d_value);
            Py_DECREF(d_value);
            Py_DECREF(d_key);
            if (res < 0) {
                return NULL;
            }
        }
    }
    Py_RETURN_NONE;
}


/*[clinic input]
@critical_section
BaseException.with_traceback
    tb: object
    /

Set self.__traceback__ to tb and return self.
[clinic start generated code]*/

static PyObject *
BaseException_with_traceback_impl(PyBaseExceptionObject *self, PyObject *tb)
/*[clinic end generated code: output=81e92f2387927f10 input=b5fb64d834717e36]*/
{
    if (BaseException___traceback___set_impl(self, tb) < 0){
        return NULL;
    }
    return Py_NewRef(self);
}

/*[clinic input]
@critical_section
BaseException.add_note
    note: object(subclass_of="&PyUnicode_Type")
    /

Add a note to the exception
[clinic start generated code]*/

static PyObject *
BaseException_add_note_impl(PyBaseExceptionObject *self, PyObject *note)
/*[clinic end generated code: output=fb7cbcba611c187b input=e60a6b6e9596acaf]*/
{
    PyObject *notes;
    if (PyObject_GetOptionalAttr((PyObject *)self, &_Py_ID(__notes__), &notes) < 0) {
        return NULL;
    }
    if (notes == NULL) {
        notes = PyList_New(0);
        if (notes == NULL) {
            return NULL;
        }
        if (PyObject_SetAttr((PyObject *)self, &_Py_ID(__notes__), notes) < 0) {
            Py_DECREF(notes);
            return NULL;
        }
    }
    else if (!PyList_Check(notes)) {
        Py_DECREF(notes);
        PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list");
        return NULL;
    }
    if (PyList_Append(notes, note) < 0) {
        Py_DECREF(notes);
        return NULL;
    }
    Py_DECREF(notes);
    Py_RETURN_NONE;
}

static PyMethodDef BaseException_methods[] = {
    BASEEXCEPTION___REDUCE___METHODDEF
    BASEEXCEPTION___SETSTATE___METHODDEF
    BASEEXCEPTION_WITH_TRACEBACK_METHODDEF
    BASEEXCEPTION_ADD_NOTE_METHODDEF
    {NULL, NULL, 0, NULL},
};

/*[clinic input]
@critical_section
@getter
BaseException.args
[clinic start generated code]*/

static PyObject *
BaseException_args_get_impl(PyBaseExceptionObject *self)
/*[clinic end generated code: output=e02e34e35cf4d677 input=64282386e4d7822d]*/
{
    if (self->args == NULL) {
        Py_RETURN_NONE;
    }
    return Py_NewRef(self->args);
}

/*[clinic input]
@critical_section
@setter
BaseException.args
[clinic start generated code]*/

static int
BaseException_args_set_impl(PyBaseExceptionObject *self, PyObject *value)
/*[clinic end generated code: output=331137e11d8f9e80 input=2400047ea5970a84]*/
{
    PyObject *seq;
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
        return -1;
    }
    seq = PySequence_Tuple(value);
    if (!seq)
        return -1;
    Py_XSETREF(self->args, seq);
    return 0;
}

/*[clinic input]
@critical_section
@getter
BaseException.__traceback__
[clinic start generated code]*/

static PyObject *
BaseException___traceback___get_impl(PyBaseExceptionObject *self)
/*[clinic end generated code: output=17cf874a52339398 input=a2277f0de62170cf]*/
{
    if (self->traceback == NULL) {
        Py_RETURN_NONE;
    }
    return Py_NewRef(self->traceback);
}


/*[clinic input]
@critical_section
@setter
BaseException.__traceback__
[clinic start generated code]*/

static int
BaseException___traceback___set_impl(PyBaseExceptionObject *self,
                                     PyObject *value)
/*[clinic end generated code: output=a82c86d9f29f48f0 input=12676035676badad]*/
{
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
        return -1;
    }
    if (PyTraceBack_Check(value)) {
        Py_XSETREF(self->traceback, Py_NewRef(value));
    }
    else if (value == Py_None) {
        Py_CLEAR(self->traceback);
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "__traceback__ must be a traceback or None");
        return -1;
    }
    return 0;
}

/*[clinic input]
@critical_section
@getter
BaseException.__context__
[clinic start generated code]*/

static PyObject *
BaseException___context___get_impl(PyBaseExceptionObject *self)
/*[clinic end generated code: output=6ec5d296ce8d1c93 input=b2d22687937e66ab]*/
{
    if (self->context == NULL) {
        Py_RETURN_NONE;
    }
    return Py_NewRef(self->context);
}

/*[clinic input]
@critical_section
@setter
BaseException.__context__
[clinic start generated code]*/

static int
BaseException___context___set_impl(PyBaseExceptionObject *self,
                                   PyObject *value)
/*[clinic end generated code: output=b4cb52dcca1da3bd input=c0971adf47fa1858]*/
{
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
        return -1;
    } else if (value == Py_None) {
        value = NULL;
    } else if (!PyExceptionInstance_Check(value)) {
        PyErr_SetString(PyExc_TypeError, "exception context must be None "
                        "or derive from BaseException");
        return -1;
    } else {
        Py_INCREF(value);
    }
    Py_XSETREF(self->context, value);
    return 0;
}

/*[clinic input]
@critical_section
@getter
BaseException.__cause__
[clinic start generated code]*/

static PyObject *
BaseException___cause___get_impl(PyBaseExceptionObject *self)
/*[clinic end generated code: output=987f6c4d8a0bdbab input=40e0eac427b6e602]*/
{
    if (self->cause == NULL) {
        Py_RETURN_NONE;
    }
    return Py_NewRef(self->cause);
}

/*[clinic input]
@critical_section
@setter
BaseException.__cause__
[clinic start generated code]*/

static int
BaseException___cause___set_impl(PyBaseExceptionObject *self,
                                 PyObject *value)
/*[clinic end generated code: output=6161315398aaf541 input=e1b403c0bde3f62a]*/
{
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
        return -1;
    } else if (value == Py_None) {
        value = NULL;
    } else if (!PyExceptionInstance_Check(value)) {
        PyErr_SetString(PyExc_TypeError, "exception cause must be None "
                        "or derive from BaseException");
        return -1;
    } else {
        /* PyException_SetCause steals this reference */
        Py_INCREF(value);
    }
    PyException_SetCause((PyObject *)self, value);
    return 0;
}


static PyGetSetDef BaseException_getset[] = {
    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
     BASEEXCEPTION_ARGS_GETSETDEF
     BASEEXCEPTION___TRACEBACK___GETSETDEF
     BASEEXCEPTION___CONTEXT___GETSETDEF
     BASEEXCEPTION___CAUSE___GETSETDEF
    {NULL},
};


PyObject *
PyException_GetTraceback(PyObject *self)
{
    PyObject *traceback;
    Py_BEGIN_CRITICAL_SECTION(self);
    traceback = Py_XNewRef(PyBaseExceptionObject_CAST(self)->traceback);
    Py_END_CRITICAL_SECTION();
    return traceback;
}


int
PyException_SetTraceback(PyObject *self, PyObject *tb)
{
    int res;
    Py_BEGIN_CRITICAL_SECTION(self);
    res = BaseException___traceback___set_impl(PyBaseExceptionObject_CAST(self), tb);
    Py_END_CRITICAL_SECTION();
    return res;
}

PyObject *
PyException_GetCause(PyObject *self)
{
    PyObject *cause;
    Py_BEGIN_CRITICAL_SECTION(self);
    cause = Py_XNewRef(PyBaseExceptionObject_CAST(self)->cause);
    Py_END_CRITICAL_SECTION();
    return cause;
}

/* Steals a reference to cause */
void
PyException_SetCause(PyObject *self, PyObject *cause)
{
    Py_BEGIN_CRITICAL_SECTION(self);
    PyBaseExceptionObject *base_self = PyBaseExceptionObject_CAST(self);
    base_self->suppress_context = 1;
    Py_XSETREF(base_self->cause, cause);
    Py_END_CRITICAL_SECTION();
}

PyObject *
PyException_GetContext(PyObject *self)
{
    PyObject *context;
    Py_BEGIN_CRITICAL_SECTION(self);
    context = Py_XNewRef(PyBaseExceptionObject_CAST(self)->context);
    Py_END_CRITICAL_SECTION();
    return context;
}

/* Steals a reference to context */
void
PyException_SetContext(PyObject *self, PyObject *context)
{
    Py_BEGIN_CRITICAL_SECTION(self);
    Py_XSETREF(PyBaseExceptionObject_CAST(self)->context, context);
    Py_END_CRITICAL_SECTION();
}

PyObject *
PyException_GetArgs(PyObject *self)
{
    PyObject *args;
    Py_BEGIN_CRITICAL_SECTION(self);
    args = Py_NewRef(PyBaseExceptionObject_CAST(self)->args);
    Py_END_CRITICAL_SECTION();
    return args;
}

void
PyException_SetArgs(PyObject *self, PyObject *args)
{
    Py_BEGIN_CRITICAL_SECTION(self);
    Py_INCREF(args);
    Py_XSETREF(PyBaseExceptionObject_CAST(self)->args, args);
    Py_END_CRITICAL_SECTION();
}

const char *
PyExceptionClass_Name(PyObject *ob)
{
    assert(PyExceptionClass_Check(ob));
    return ((PyTypeObject*)ob)->tp_name;
}

static struct PyMemberDef BaseException_members[] = {
    {"__suppress_context__", Py_T_BOOL,
     offsetof(PyBaseExceptionObject, suppress_context)},
    {NULL}
};


static PyTypeObject _PyExc_BaseException = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "BaseException", /*tp_name*/
    sizeof(PyBaseExceptionObject), /*tp_basicsize*/
    0,                          /*tp_itemsize*/
    BaseException_dealloc,      /*tp_dealloc*/
    0,                          /*tp_vectorcall_offset*/
    0,                          /*tp_getattr*/
    0,                          /*tp_setattr*/
    0,                          /*tp_as_async*/
    BaseException_repr,         /*tp_repr*/
    0,                          /*tp_as_number*/
    0,                          /*tp_as_sequence*/
    0,                          /*tp_as_mapping*/
    0,                          /*tp_hash */
    0,                          /*tp_call*/
    BaseException_str,          /*tp_str*/
    PyObject_GenericGetAttr,    /*tp_getattro*/
    PyObject_GenericSetAttr,    /*tp_setattro*/
    0,                          /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASE_EXC_SUBCLASS,  /*tp_flags*/
    PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
    BaseException_traverse,     /* tp_traverse */
    BaseException_clear,        /* tp_clear */
    0,                          /* tp_richcompare */
    0,                          /* tp_weaklistoffset */
    0,                          /* tp_iter */
    0,                          /* tp_iternext */
    BaseException_methods,      /* tp_methods */
    BaseException_members,      /* tp_members */
    BaseException_getset,       /* tp_getset */
    0,                          /* tp_base */
    0,                          /* tp_dict */
    0,                          /* tp_descr_get */
    0,                          /* tp_descr_set */
    offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
    BaseException_init,         /* tp_init */
    0,                          /* tp_alloc */
    BaseException_new,          /* tp_new */
    .tp_vectorcall = BaseException_vectorcall,
};
/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
from the previous implementation and also allowing Python objects to be used
in the API */
PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;

/* note these macros omit the last semicolon so the macro invocation may
 * include it and not look strange.
 */
#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
static PyTypeObject _PyExc_ ## EXCNAME = { \
    PyVarObject_HEAD_INIT(NULL, 0) \
    # EXCNAME, \
    sizeof(PyBaseExceptionObject), \
    0, BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, \
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
    PyDoc_STR(EXCDOC), BaseException_traverse, \
    BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
    0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
    BaseException_init, 0, BaseException_new,\
}; \
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME

#define MiddlingExtendsExceptionEx(EXCBASE, EXCNAME, PYEXCNAME, EXCSTORE, EXCDOC) \
PyTypeObject _PyExc_ ## EXCNAME = { \
    PyVarObject_HEAD_INIT(NULL, 0) \
    # PYEXCNAME, \
    sizeof(Py ## EXCSTORE ## Object), \
    0, EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, 0, \
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
    PyDoc_STR(EXCDOC), EXCSTORE ## _traverse, \
    EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
    EXCSTORE ## _init, 0, 0, \
};

#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
    static MiddlingExtendsExceptionEx( \
        EXCBASE, EXCNAME, EXCNAME, EXCSTORE, EXCDOC); \
    PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME

#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \
                                EXCMETHODS, EXCMEMBERS, EXCGETSET, \
                                EXCSTR, EXCREPR, EXCDOC) \
static PyTypeObject _PyExc_ ## EXCNAME = { \
    PyVarObject_HEAD_INIT(NULL, 0) \
    # EXCNAME, \
    sizeof(Py ## EXCSTORE ## Object), 0, \
    EXCSTORE ## _dealloc, 0, 0, 0, 0, EXCREPR, 0, 0, 0, 0, 0, \
    EXCSTR, 0, 0, 0, \
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
    PyDoc_STR(EXCDOC), EXCSTORE ## _traverse, \
    EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
    EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \
    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
    EXCSTORE ## _init, 0, EXCNEW,\
}; \
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME


/*
 *    Exception extends BaseException
 */
SimpleExtendsException(PyExc_BaseException, Exception,
                       "Common base class for all non-exit exceptions.");


/*
 *    TypeError extends Exception
 */
SimpleExtendsException(PyExc_Exception, TypeError,
                       "Inappropriate argument type.");


/*
 *    StopAsyncIteration extends Exception
 */
SimpleExtendsException(PyExc_Exception, StopAsyncIteration,
                       "Signal the end from iterator.__anext__().");


/*
 *    StopIteration extends Exception
 */

static PyMemberDef StopIteration_members[] = {
    {"value", _Py_T_OBJECT, offsetof(PyStopIterationObject, value), 0,
        PyDoc_STR("generator return value")},
    {NULL}  /* Sentinel */
};

static inline PyStopIterationObject *
PyStopIterationObject_CAST(PyObject *self)
{
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_StopIteration));
    return (PyStopIterationObject *)self;
}

static int
StopIteration_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    Py_ssize_t size = PyTuple_GET_SIZE(args);
    PyObject *value;

    if (BaseException_init(op, args, kwds) == -1)
        return -1;
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
    Py_CLEAR(self->value);
    if (size > 0)
        value = PyTuple_GET_ITEM(args, 0);
    else
        value = Py_None;
    self->value = Py_NewRef(value);
    return 0;
}

static int
StopIteration_clear(PyObject *op)
{
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
    Py_CLEAR(self->value);
    return BaseException_clear(op);
}

static void
StopIteration_dealloc(PyObject *self)
{
    PyObject_GC_UnTrack(self);
    (void)StopIteration_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
StopIteration_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
    Py_VISIT(self->value);
    return BaseException_traverse(op, visit, arg);
}

ComplexExtendsException(PyExc_Exception, StopIteration, StopIteration,
                        0, 0, StopIteration_members, 0, 0, 0,
                        "Signal the end from iterator.__next__().");


/*
 *    GeneratorExit extends BaseException
 */
SimpleExtendsException(PyExc_BaseException, GeneratorExit,
                       "Request that a generator exit.");


/*
 *    SystemExit extends BaseException
 */

static inline PySystemExitObject *
PySystemExitObject_CAST(PyObject *self)
{
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_SystemExit));
    return (PySystemExitObject *)self;
}

static int
SystemExit_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    Py_ssize_t size = PyTuple_GET_SIZE(args);

    if (BaseException_init(op, args, kwds) == -1)
        return -1;

    PySystemExitObject *self = PySystemExitObject_CAST(op);
    if (size == 0)
        return 0;
    if (size == 1) {
        Py_XSETREF(self->code, Py_NewRef(PyTuple_GET_ITEM(args, 0)));
    }
    else { /* size > 1 */
        Py_XSETREF(self->code, Py_NewRef(args));
    }
    return 0;
}

static int
SystemExit_clear(PyObject *op)
{
    PySystemExitObject *self = PySystemExitObject_CAST(op);
    Py_CLEAR(self->code);
    return BaseException_clear(op);
}

static void
SystemExit_dealloc(PyObject *self)
{
    _PyObject_GC_UNTRACK(self);
    (void)SystemExit_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
SystemExit_traverse(PyObject *op, visitproc visit, void *arg)
{
    PySystemExitObject *self = PySystemExitObject_CAST(op);
    Py_VISIT(self->code);
    return BaseException_traverse(op, visit, arg);
}

static PyMemberDef SystemExit_members[] = {
    {"code", _Py_T_OBJECT, offsetof(PySystemExitObject, code), 0,
        PyDoc_STR("exception code")},
    {NULL}  /* Sentinel */
};

ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
                        0, 0, SystemExit_members, 0, 0, 0,
                        "Request to exit from the interpreter.");

/*
 *    BaseExceptionGroup extends BaseException
 *    ExceptionGroup extends BaseExceptionGroup and Exception
 */


static inline PyBaseExceptionGroupObject*
PyBaseExceptionGroupObject_CAST(PyObject *exc)
{
    assert(_PyBaseExceptionGroup_Check(exc));
    return (PyBaseExceptionGroupObject *)exc;
}

static PyObject *
BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    struct _Py_exc_state *state = get_exc_state();
    PyTypeObject *PyExc_ExceptionGroup =
        (PyTypeObject*)state->PyExc_ExceptionGroup;

    PyObject *message = NULL;
    PyObject *exceptions = NULL;
    PyObject *exceptions_str = NULL;

    if (!PyArg_ParseTuple(args,
                          "UO:BaseExceptionGroup.__new__",
                          &message,
                          &exceptions)) {
        return NULL;
    }

    if (!PySequence_Check(exceptions)) {
        PyErr_SetString(
            PyExc_TypeError,
            "second argument (exceptions) must be a sequence");
        return NULL;
    }

    /* Save initial exceptions sequence as a string in case sequence is mutated */
    if (!PyList_Check(exceptions) && !PyTuple_Check(exceptions)) {
        exceptions_str = PyObject_Repr(exceptions);
        if (exceptions_str == NULL) {
            /* We don't hold a reference to exceptions, so clear it before
             * attempting a decref in the cleanup.
             */
            exceptions = NULL;
            goto error;
        }
    }

    exceptions = PySequence_Tuple(exceptions);
    if (!exceptions) {
        goto error;
    }

    /* We are now holding a ref to the exceptions tuple */

    Py_ssize_t numexcs = PyTuple_GET_SIZE(exceptions);
    if (numexcs == 0) {
        PyErr_SetString(
            PyExc_ValueError,
            "second argument (exceptions) must be a non-empty sequence");
        goto error;
    }

    bool nested_base_exceptions = false;
    for (Py_ssize_t i = 0; i < numexcs; i++) {
        PyObject *exc = PyTuple_GET_ITEM(exceptions, i);
        if (!exc) {
            goto error;
        }
        if (!PyExceptionInstance_Check(exc)) {
            PyErr_Format(
                PyExc_ValueError,
                "Item %zd of second argument (exceptions) is not an exception",
                i);
            goto error;
        }
        int is_nonbase_exception = PyObject_IsInstance(exc, PyExc_Exception);
        if (is_nonbase_exception < 0) {
            goto error;
        }
        else if (is_nonbase_exception == 0) {
            nested_base_exceptions = true;
        }
    }

    PyTypeObject *cls = type;
    if (cls == PyExc_ExceptionGroup) {
        if (nested_base_exceptions) {
            PyErr_SetString(PyExc_TypeError,
                "Cannot nest BaseExceptions in an ExceptionGroup");
            goto error;
        }
    }
    else if (cls == (PyTypeObject*)PyExc_BaseExceptionGroup) {
        if (!nested_base_exceptions) {
            /* All nested exceptions are Exception subclasses,
             * wrap them in an ExceptionGroup
             */
            cls = PyExc_ExceptionGroup;
        }
    }
    else {
        /* user-defined subclass */
        if (nested_base_exceptions) {
            int nonbase = PyObject_IsSubclass((PyObject*)cls, PyExc_Exception);
            if (nonbase == -1) {
                goto error;
            }
            else if (nonbase == 1) {
                PyErr_Format(PyExc_TypeError,
                    "Cannot nest BaseExceptions in '%.200s'",
                    cls->tp_name);
                goto error;
            }
        }
    }

    if (!cls) {
        /* Don't crash during interpreter shutdown
         * (PyExc_ExceptionGroup may have been cleared)
         */
        cls = (PyTypeObject*)PyExc_BaseExceptionGroup;
    }
    PyBaseExceptionGroupObject *self =
        PyBaseExceptionGroupObject_CAST(BaseException_new(cls, args, kwds));
    if (!self) {
        goto error;
    }

    self->msg = Py_NewRef(message);
    self->excs = exceptions;
    self->excs_str = exceptions_str;
    return (PyObject*)self;
error:
    Py_XDECREF(exceptions);
    Py_XDECREF(exceptions_str);
    return NULL;
}

PyObject *
_PyExc_CreateExceptionGroup(const char *msg_str, PyObject *excs)
{
    PyObject *msg = PyUnicode_FromString(msg_str);
    if (!msg) {
        return NULL;
    }
    PyObject *args = _PyTuple_FromPairSteal(msg, Py_NewRef(excs));
    if (!args) {
        return NULL;
    }
    PyObject *result = PyObject_CallObject(PyExc_BaseExceptionGroup, args);
    Py_DECREF(args);
    return result;
}

static int
BaseExceptionGroup_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) {
        return -1;
    }
    if (BaseException_init(self, args, kwds) == -1) {
        return -1;
    }
    return 0;
}

static int
BaseExceptionGroup_clear(PyObject *op)
{
    PyBaseExceptionGroupObject *self = PyBaseExceptionGroupObject_CAST(op);
    Py_CLEAR(self->msg);
    Py_CLEAR(self->excs);
    Py_CLEAR(self->excs_str);
    return BaseException_clear(op);
}

static void
BaseExceptionGroup_dealloc(PyObject *self)
{
    _PyObject_GC_UNTRACK(self);
    (void)BaseExceptionGroup_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
BaseExceptionGroup_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyBaseExceptionGroupObject *self = PyBaseExceptionGroupObject_CAST(op);
    Py_VISIT(self->msg);
    Py_VISIT(self->excs);
    Py_VISIT(self->excs_str);
    return BaseException_traverse(op, visit, arg);
}

static PyObject *
BaseExceptionGroup_str(PyObject *op)
{
    PyBaseExceptionGroupObject *self = PyBaseExceptionGroupObject_CAST(op);
    assert(self->msg);
    assert(PyUnicode_Check(self->msg));

    assert(PyTuple_CheckExact(self->excs));
    Py_ssize_t num_excs = PyTuple_Size(self->excs);
    return PyUnicode_FromFormat(
        "%S (%zd sub-exception%s)",
        self->msg, num_excs, num_excs > 1 ? "s" : "");
}

static PyObject *
BaseExceptionGroup_repr(PyObject *op)
{
    PyBaseExceptionGroupObject *self = PyBaseExceptionGroupObject_CAST(op);
    assert(self->msg);

    PyObject *exceptions_str = NULL;

    /* Use the saved exceptions string for custom sequences. */
    if (self->excs_str) {
        exceptions_str = Py_NewRef(self->excs_str);
    }
    else {
        assert(self->excs);

        /* Older versions delegated to BaseException, inserting the current
         * value of self.args[1]; but this can be mutable and go out-of-sync
         * with self.exceptions. Instead, use self.exceptions for accuracy,
         * making it look like self.args[1] for backwards compatibility. */
        assert(PyTuple_Check(self->args));
        if (PyTuple_GET_SIZE(self->args) == 2 && PyList_Check(PyTuple_GET_ITEM(self->args, 1))) {
            PyObject *exceptions_list = PySequence_List(self->excs);
            if (!exceptions_list) {
                return NULL;
            }

            exceptions_str = PyObject_Repr(exceptions_list);
            Py_DECREF(exceptions_list);
        }
        else {
            exceptions_str = PyObject_Repr(self->excs);
        }

        if (!exceptions_str) {
            return NULL;
        }
    }

    assert(exceptions_str != NULL);

    const char *name = _PyType_Name(Py_TYPE(self));
    PyObject *repr = PyUnicode_FromFormat(
        "%s(%R, %U)", name,
        self->msg, exceptions_str);

    Py_DECREF(exceptions_str);
    return repr;
}

/*[clinic input]
@critical_section
BaseExceptionGroup.derive
    excs: object
    /
[clinic start generated code]*/

static PyObject *
BaseExceptionGroup_derive_impl(PyBaseExceptionGroupObject *self,
                               PyObject *excs)
/*[clinic end generated code: output=4307564218dfbf06 input=f72009d38e98cec1]*/
{
    PyObject *init_args = _PyTuple_FromPair(self->msg, excs);
    if (!init_args) {
        return NULL;
    }
    PyObject *eg = PyObject_CallObject(
        PyExc_BaseExceptionGroup, init_args);
    Py_DECREF(init_args);
    return eg;
}

static int
exceptiongroup_subset(
    PyBaseExceptionGroupObject *_orig, PyObject *excs, PyObject **result)
{
    /* Sets *result to an ExceptionGroup wrapping excs with metadata from
     * _orig. If excs is empty, sets *result to NULL.
     * Returns 0 on success and -1 on error.

     * This function is used by split() to construct the match/rest parts,
     * so excs is the matching or non-matching sub-sequence of orig->excs
     * (this function does not verify that it is a subsequence).
     */
    PyObject *orig = (PyObject *)_orig;

    *result = NULL;
    Py_ssize_t num_excs = PySequence_Size(excs);
    if (num_excs < 0) {
        return -1;
    }
    else if (num_excs == 0) {
        return 0;
    }

    PyObject *eg = PyObject_CallMethod(
        orig, "derive", "(O)", excs);
    if (!eg) {
        return -1;
    }

    if (!_PyBaseExceptionGroup_Check(eg)) {
        PyErr_SetString(PyExc_TypeError,
            "derive must return an instance of BaseExceptionGroup");
        goto error;
    }

    /* Now we hold a reference to the new eg */

    PyObject *tb = PyException_GetTraceback(orig);
    if (tb) {
        int res = PyException_SetTraceback(eg, tb);
        Py_DECREF(tb);
        if (res < 0) {
            goto error;
        }
    }
    PyException_SetContext(eg, PyException_GetContext(orig));
    PyException_SetCause(eg, PyException_GetCause(orig));

    PyObject *notes;
    if (PyObject_GetOptionalAttr(orig, &_Py_ID(__notes__), &notes) < 0) {
        goto error;
    }
    if (notes) {
        if (PySequence_Check(notes)) {
            /* Make a copy so the parts have independent notes lists. */
            PyObject *notes_copy = PySequence_List(notes);
            Py_DECREF(notes);
            if (notes_copy == NULL) {
                goto error;
            }
            int res = PyObject_SetAttr(eg, &_Py_ID(__notes__), notes_copy);
            Py_DECREF(notes_copy);
            if (res < 0) {
                goto error;
            }
        }
        else {
            /* __notes__ is supposed to be a list, and split() is not a
             * good place to report earlier user errors, so we just ignore
             * notes of non-sequence type.
             */
            Py_DECREF(notes);
        }
    }

    *result = eg;
    return 0;
error:
    Py_DECREF(eg);
    return -1;
}

typedef enum {
    /* Exception type or tuple of thereof */
    EXCEPTION_GROUP_MATCH_BY_TYPE = 0,
    /* A PyFunction returning True for matching exceptions */
    EXCEPTION_GROUP_MATCH_BY_PREDICATE = 1,
    /* A set of the IDs of leaf exceptions to include in the result.
     * This matcher type is used internally by the interpreter
     * to construct reraised exceptions.
     */
    EXCEPTION_GROUP_MATCH_INSTANCE_IDS = 2
} _exceptiongroup_split_matcher_type;

static int
get_matcher_type(PyObject *value,
                 _exceptiongroup_split_matcher_type *type)
{
    assert(value);

    if (PyCallable_Check(value) && !PyType_Check(value)) {
        *type = EXCEPTION_GROUP_MATCH_BY_PREDICATE;
        return 0;
    }

    if (PyExceptionClass_Check(value)) {
        *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
        return 0;
    }

    if (PyTuple_CheckExact(value)) {
        Py_ssize_t n = PyTuple_GET_SIZE(value);
        for (Py_ssize_t i=0; i<n; i++) {
            if (!PyExceptionClass_Check(PyTuple_GET_ITEM(value, i))) {
                goto error;
            }
        }
        *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
        return 0;
    }

error:
    PyErr_SetString(
        PyExc_TypeError,
        "expected an exception type, a tuple of exception types, or a callable (other than a class)");
    return -1;
}

static int
exceptiongroup_split_check_match(PyObject *exc,
                                 _exceptiongroup_split_matcher_type matcher_type,
                                 PyObject *matcher_value)
{
    switch (matcher_type) {
    case EXCEPTION_GROUP_MATCH_BY_TYPE: {
        assert(PyExceptionClass_Check(matcher_value) ||
               PyTuple_CheckExact(matcher_value));
        return PyErr_GivenExceptionMatches(exc, matcher_value);
    }
    case EXCEPTION_GROUP_MATCH_BY_PREDICATE: {
        assert(PyCallable_Check(matcher_value) && !PyType_Check(matcher_value));
        PyObject *exc_matches = PyObject_CallOneArg(matcher_value, exc);
        if (exc_matches == NULL) {
            return -1;
        }
        int is_true = PyObject_IsTrue(exc_matches);
        Py_DECREF(exc_matches);
        return is_true;
    }
    case EXCEPTION_GROUP_MATCH_INSTANCE_IDS: {
        assert(PySet_Check(matcher_value));
        if (!_PyBaseExceptionGroup_Check(exc)) {
            PyObject *exc_id = PyLong_FromVoidPtr(exc);
            if (exc_id == NULL) {
                return -1;
            }
            int res = PySet_Contains(matcher_value, exc_id);
            Py_DECREF(exc_id);
            return res;
        }
        return 0;
    }
    }
    return 0;
}

typedef struct {
    PyObject *match;
    PyObject *rest;
} _exceptiongroup_split_result;

static int
exceptiongroup_split_recursive(PyObject *exc,
                               _exceptiongroup_split_matcher_type matcher_type,
                               PyObject *matcher_value,
                               bool construct_rest,
                               _exceptiongroup_split_result *result)
{
    result->match = NULL;
    result->rest = NULL;

    int is_match = exceptiongroup_split_check_match(
        exc, matcher_type, matcher_value);
    if (is_match < 0) {
        return -1;
    }

    if (is_match) {
        /* Full match */
        result->match = Py_NewRef(exc);
        return 0;
    }
    else if (!_PyBaseExceptionGroup_Check(exc)) {
        /* Leaf exception and no match */
        if (construct_rest) {
            result->rest = Py_NewRef(exc);
        }
        return 0;
    }

    /* Partial match */

    PyBaseExceptionGroupObject *eg = PyBaseExceptionGroupObject_CAST(exc);
    assert(PyTuple_CheckExact(eg->excs));
    Py_ssize_t num_excs = PyTuple_Size(eg->excs);
    if (num_excs < 0) {
        return -1;
    }
    assert(num_excs > 0); /* checked in constructor, and excs is read-only */

    int retval = -1;
    PyObject *match_list = PyList_New(0);
    if (!match_list) {
        return -1;
    }

    PyObject *rest_list = NULL;
    if (construct_rest) {
        rest_list = PyList_New(0);
        if (!rest_list) {
            goto done;
        }
    }
    /* recursive calls */
    for (Py_ssize_t i = 0; i < num_excs; i++) {
        PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
        _exceptiongroup_split_result rec_result;
        if (_Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) {
            goto done;
        }
        if (exceptiongroup_split_recursive(
                e, matcher_type, matcher_value,
                construct_rest, &rec_result) < 0) {
            assert(!rec_result.match);
            assert(!rec_result.rest);
            _Py_LeaveRecursiveCall();
            goto done;
        }
        _Py_LeaveRecursiveCall();
        if (rec_result.match) {
            assert(PyList_CheckExact(match_list));
            if (PyList_Append(match_list, rec_result.match) < 0) {
                Py_DECREF(rec_result.match);
                Py_XDECREF(rec_result.rest);
                goto done;
            }
            Py_DECREF(rec_result.match);
        }
        if (rec_result.rest) {
            assert(construct_rest);
            assert(PyList_CheckExact(rest_list));
            if (PyList_Append(rest_list, rec_result.rest) < 0) {
                Py_DECREF(rec_result.rest);
                goto done;
            }
            Py_DECREF(rec_result.rest);
        }
    }

    /* construct result */
    if (exceptiongroup_subset(eg, match_list, &result->match) < 0) {
        goto done;
    }

    if (construct_rest) {
        assert(PyList_CheckExact(rest_list));
        if (exceptiongroup_subset(eg, rest_list, &result->rest) < 0) {
            Py_CLEAR(result->match);
            goto done;
        }
    }
    retval = 0;
done:
    Py_DECREF(match_list);
    Py_XDECREF(rest_list);
    if (retval < 0) {
        Py_CLEAR(result->match);
        Py_CLEAR(result->rest);
    }
    return retval;
}

/*[clinic input]
@critical_section
BaseExceptionGroup.split
    matcher_value: object
    /
[clinic start generated code]*/

static PyObject *
BaseExceptionGroup_split_impl(PyBaseExceptionGroupObject *self,
                              PyObject *matcher_value)
/*[clinic end generated code: output=d74db579da4df6e2 input=0c5cfbfed57e0052]*/
{
    _exceptiongroup_split_matcher_type matcher_type;
    if (get_matcher_type(matcher_value, &matcher_type) < 0) {
        return NULL;
    }

    _exceptiongroup_split_result split_result;
    bool construct_rest = true;
    if (exceptiongroup_split_recursive(
            (PyObject *)self, matcher_type, matcher_value,
            construct_rest, &split_result) < 0) {
        return NULL;
    }

    assert(_Py_IsStaticImmortal(Py_None));
    PyObject *result = _PyTuple_FromPairSteal(
            split_result.match ? split_result.match : Py_None,
            split_result.rest ? split_result.rest : Py_None);

    return result;
}

/*[clinic input]
@critical_section
BaseExceptionGroup.subgroup
    matcher_value: object
    /
[clinic start generated code]*/

static PyObject *
BaseExceptionGroup_subgroup_impl(PyBaseExceptionGroupObject *self,
                                 PyObject *matcher_value)
/*[clinic end generated code: output=07dbec8f77d4dd8e input=988ffdd755a151ce]*/
{
    _exceptiongroup_split_matcher_type matcher_type;
    if (get_matcher_type(matcher_value, &matcher_type) < 0) {
        return NULL;
    }

    _exceptiongroup_split_result split_result;
    bool construct_rest = false;
    if (exceptiongroup_split_recursive(
            (PyObject *)self, matcher_type, matcher_value,
            construct_rest, &split_result) < 0) {
        return NULL;
    }

    PyObject *result = Py_NewRef(
            split_result.match ? split_result.match : Py_None);

    Py_XDECREF(split_result.match);
    assert(!split_result.rest);
    return result;
}

static int
collect_exception_group_leaf_ids(PyObject *exc, PyObject *leaf_ids)
{
    if (Py_IsNone(exc)) {
        return 0;
    }

    assert(PyExceptionInstance_Check(exc));
    assert(PySet_Check(leaf_ids));

    /* Add IDs of all leaf exceptions in exc to the leaf_ids set */

    if (!_PyBaseExceptionGroup_Check(exc)) {
        PyObject *exc_id = PyLong_FromVoidPtr(exc);
        if (exc_id == NULL) {
            return -1;
        }
        int res = PySet_Add(leaf_ids, exc_id);
        Py_DECREF(exc_id);
        return res;
    }
    PyBaseExceptionGroupObject *eg = PyBaseExceptionGroupObject_CAST(exc);
    Py_ssize_t num_excs = PyTuple_GET_SIZE(eg->excs);
    /* recursive calls */
    for (Py_ssize_t i = 0; i < num_excs; i++) {
        PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
        if (_Py_EnterRecursiveCall(" in collect_exception_group_leaf_ids")) {
            return -1;
        }
        int res = collect_exception_group_leaf_ids(e, leaf_ids);
        _Py_LeaveRecursiveCall();
        if (res < 0) {
            return -1;
        }
    }
    return 0;
}

/* This function is used by the interpreter to construct reraised
 * exception groups. It takes an exception group eg and a list
 * of exception groups keep and returns the sub-exception group
 * of eg which contains all leaf exceptions that are contained
 * in any exception group in keep.
 */
static PyObject *
exception_group_projection(PyObject *eg, PyObject *keep)
{
    assert(_PyBaseExceptionGroup_Check(eg));
    assert(PyList_CheckExact(keep));

    PyObject *leaf_ids = PySet_New(NULL);
    if (!leaf_ids) {
        return NULL;
    }

    Py_ssize_t n = PyList_GET_SIZE(keep);
    for (Py_ssize_t i = 0; i < n; i++) {
        PyObject *e = PyList_GET_ITEM(keep, i);
        assert(e != NULL);
        assert(_PyBaseExceptionGroup_Check(e));
        if (collect_exception_group_leaf_ids(e, leaf_ids) < 0) {
            Py_DECREF(leaf_ids);
            return NULL;
        }
    }

    _exceptiongroup_split_result split_result;
    bool construct_rest = false;
    int err = exceptiongroup_split_recursive(
                eg, EXCEPTION_GROUP_MATCH_INSTANCE_IDS, leaf_ids,
                construct_rest, &split_result);
    Py_DECREF(leaf_ids);
    if (err < 0) {
        return NULL;
    }

    PyObject *result = split_result.match ?
        split_result.match : Py_NewRef(Py_None);
    assert(split_result.rest == NULL);
    return result;
}

static bool
is_same_exception_metadata(PyObject *exc1, PyObject *exc2)
{
    assert(PyExceptionInstance_Check(exc1));
    assert(PyExceptionInstance_Check(exc2));

    PyBaseExceptionObject *e1 = (PyBaseExceptionObject *)exc1;
    PyBaseExceptionObject *e2 = (PyBaseExceptionObject *)exc2;

    return (e1->notes == e2->notes &&
            e1->traceback == e2->traceback &&
            e1->cause == e2->cause &&
            e1->context == e2->context);
}

/*
   This function is used by the interpreter to calculate
   the exception group to be raised at the end of a
   try-except* construct.

   orig: the original except that was caught.
   excs: a list of exceptions that were raised/reraised
         in the except* clauses.

   Calculates an exception group to raise. It contains
   all exceptions in excs, where those that were reraised
   have same nesting structure as in orig, and those that
   were raised (if any) are added as siblings in a new EG.

   Returns NULL and sets an exception on failure.
*/
PyObject *
_PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
{
    /* orig must be a raised & caught exception, so it has a traceback */
    assert(PyExceptionInstance_Check(orig));
    assert(PyBaseExceptionObject_CAST(orig)->traceback != NULL);

    assert(PyList_Check(excs));

    Py_ssize_t numexcs = PyList_GET_SIZE(excs);

    if (numexcs == 0) {
        return Py_NewRef(Py_None);
    }

    if (!_PyBaseExceptionGroup_Check(orig)) {
        /* a naked exception was caught and wrapped. Only one except* clause
         * could have executed,so there is at most one exception to raise.
         */

        assert(numexcs == 1 || (numexcs == 2 && PyList_GET_ITEM(excs, 1) == Py_None));

        PyObject *e = PyList_GET_ITEM(excs, 0);
        assert(e != NULL);
        return Py_NewRef(e);
    }

    PyObject *raised_list = PyList_New(0);
    if (raised_list == NULL) {
        return NULL;
    }
    PyObject* reraised_list = PyList_New(0);
    if (reraised_list == NULL) {
        Py_DECREF(raised_list);
        return NULL;
    }

    /* Now we are holding refs to raised_list and reraised_list */

    PyObject *result = NULL;

    /* Split excs into raised and reraised by comparing metadata with orig */
    for (Py_ssize_t i = 0; i < numexcs; i++) {
        PyObject *e = PyList_GET_ITEM(excs, i);
        assert(e != NULL);
        if (Py_IsNone(e)) {
            continue;
        }
        bool is_reraise = is_same_exception_metadata(e, orig);
        PyObject *append_list = is_reraise ? reraised_list : raised_list;
        if (PyList_Append(append_list, e) < 0) {
            goto done;
        }
    }

    PyObject *reraised_eg = exception_group_projection(orig, reraised_list);
    if (reraised_eg == NULL) {
        goto done;
    }

    if (!Py_IsNone(reraised_eg)) {
        assert(is_same_exception_metadata(reraised_eg, orig));
    }
    Py_ssize_t num_raised = PyList_GET_SIZE(raised_list);
    if (num_raised == 0) {
        result = reraised_eg;
    }
    else if (num_raised > 0) {
        int res = 0;
        if (!Py_IsNone(reraised_eg)) {
            res = PyList_Append(raised_list, reraised_eg);
        }
        Py_DECREF(reraised_eg);
        if (res < 0) {
            goto done;
        }
        if (PyList_GET_SIZE(raised_list) > 1) {
            result = _PyExc_CreateExceptionGroup("", raised_list);
        }
        else {
            result = Py_NewRef(PyList_GetItem(raised_list, 0));
        }
        if (result == NULL) {
            goto done;
        }
    }

done:
    Py_XDECREF(raised_list);
    Py_XDECREF(reraised_list);
    return result;
}

PyObject *
PyUnstable_Exc_PrepReraiseStar(PyObject *orig, PyObject *excs)
{
    if (orig == NULL || !PyExceptionInstance_Check(orig)) {
        PyErr_SetString(PyExc_TypeError, "orig must be an exception instance");
        return NULL;
    }
    if (excs == NULL || !PyList_Check(excs)) {
        PyErr_SetString(PyExc_TypeError,
                        "excs must be a list of exception instances");
        return NULL;
    }
    Py_ssize_t numexcs = PyList_GET_SIZE(excs);
    for (Py_ssize_t i = 0; i < numexcs; i++) {
        PyObject *exc = PyList_GET_ITEM(excs, i);
        if (exc == NULL || !(PyExceptionInstance_Check(exc) || Py_IsNone(exc))) {
            PyErr_Format(PyExc_TypeError,
                         "item %zd of excs is not an exception", i);
            return NULL;
        }
    }

    /* Make sure that orig has something as traceback, in the interpreter
     * it always does because it's a raised exception.
     */
    PyObject *tb = PyException_GetTraceback(orig);

    if (tb == NULL) {
        PyErr_Format(PyExc_ValueError, "orig must be a raised exception");
        return NULL;
    }
    Py_DECREF(tb);

    return _PyExc_PrepReraiseStar(orig, excs);
}

static PyMemberDef BaseExceptionGroup_members[] = {
    {"message", _Py_T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), Py_READONLY,
        PyDoc_STR("exception message")},
    {"exceptions", _Py_T_OBJECT, offsetof(PyBaseExceptionGroupObject, excs), Py_READONLY,
        PyDoc_STR("nested exceptions")},
    {NULL}  /* Sentinel */
};

static PyMethodDef BaseExceptionGroup_methods[] = {
    {"__class_getitem__", Py_GenericAlias,
      METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
    BASEEXCEPTIONGROUP_DERIVE_METHODDEF
    BASEEXCEPTIONGROUP_SPLIT_METHODDEF
    BASEEXCEPTIONGROUP_SUBGROUP_METHODDEF
    {NULL}
};

ComplexExtendsException(PyExc_BaseException, BaseExceptionGroup,
    BaseExceptionGroup, BaseExceptionGroup_new /* new */,
    BaseExceptionGroup_methods, BaseExceptionGroup_members,
    0 /* getset */, BaseExceptionGroup_str, BaseExceptionGroup_repr,
    "A combination of multiple unrelated exceptions.");

/*
 *    ExceptionGroup extends BaseExceptionGroup, Exception
 */
static PyObject*
create_exception_group_class(void) {
    struct _Py_exc_state *state = get_exc_state();

    PyObject *bases = _PyTuple_FromPair(
        PyExc_BaseExceptionGroup, PyExc_Exception);
    if (bases == NULL) {
        return NULL;
    }

    assert(!state->PyExc_ExceptionGroup);
    state->PyExc_ExceptionGroup = PyErr_NewException(
        "builtins.ExceptionGroup", bases, NULL);

    Py_DECREF(bases);
    return state->PyExc_ExceptionGroup;
}

/*
 *    KeyboardInterrupt extends BaseException
 */
SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
                       "Program interrupted by user.");


/*
 *    ImportError extends Exception
 */

static inline PyImportErrorObject *
PyImportErrorObject_CAST(PyObject *self)
{
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_ImportError));
    return (PyImportErrorObject *)self;
}

static int
ImportError_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"name", "path", "name_from", 0};
    PyObject *empty_tuple;
    PyObject *msg = NULL;
    PyObject *name = NULL;
    PyObject *path = NULL;
    PyObject *name_from = NULL;

    if (BaseException_init(op, args, NULL) == -1)
        return -1;

    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
    empty_tuple = PyTuple_New(0);
    if (!empty_tuple)
        return -1;
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist,
                                     &name, &path, &name_from)) {
        Py_DECREF(empty_tuple);
        return -1;
    }
    Py_DECREF(empty_tuple);

    Py_XSETREF(self->name, Py_XNewRef(name));
    Py_XSETREF(self->path, Py_XNewRef(path));
    Py_XSETREF(self->name_from, Py_XNewRef(name_from));

    if (PyTuple_GET_SIZE(args) == 1) {
        msg = Py_NewRef(PyTuple_GET_ITEM(args, 0));
    }
    Py_XSETREF(self->msg, msg);

    return 0;
}

static int
ImportError_clear(PyObject *op)
{
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
    Py_CLEAR(self->msg);
    Py_CLEAR(self->name);
    Py_CLEAR(self->path);
    Py_CLEAR(self->name_from);
    return BaseException_clear(op);
}

static void
ImportError_dealloc(PyObject *self)
{
    _PyObject_GC_UNTRACK(self);
    (void)ImportError_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
ImportError_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
    Py_VISIT(self->msg);
    Py_VISIT(self->name);
    Py_VISIT(self->path);
    Py_VISIT(self->name_from);
    return BaseException_traverse(op, visit, arg);
}

static PyObject *
ImportError_str(PyObject *op)
{
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
    if (self->msg && PyUnicode_CheckExact(self->msg)) {
        return Py_NewRef(self->msg);
    }
    return BaseException_str(op);
}

static PyObject *
ImportError_getstate(PyObject *op)
{
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
    PyObject *dict = self->dict;
    if (self->name || self->path || self->name_from) {
        dict = dict ? PyDict_Copy(dict) : PyDict_New();
        if (dict == NULL)
            return NULL;
        if (self->name && PyDict_SetItem(dict, &_Py_ID(name), self->name) < 0) {
            Py_DECREF(dict);
            return NULL;
        }
        if (self->path && PyDict_SetItem(dict, &_Py_ID(path), self->path) < 0) {
            Py_DECREF(dict);
            return NULL;
        }
        if (self->name_from && PyDict_SetItem(dict, &_Py_ID(name_from), self->name_from) < 0) {
            Py_DECREF(dict);
            return NULL;
        }
        return dict;
    }
    else if (dict) {
        return Py_NewRef(dict);
    }
    else {
        Py_RETURN_NONE;
    }
}

/* Pickling support */
static PyObject *
ImportError_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    PyObject *res;
    PyObject *state = ImportError_getstate(self);
    if (state == NULL)
        return NULL;
    PyBaseExceptionObject *exc = PyBaseExceptionObject_CAST(self);
    if (state == Py_None)
        res = _PyTuple_FromPair((PyObject *)Py_TYPE(self), exc->args);
    else
        res = PyTuple_Pack(3, Py_TYPE(self), exc->args, state);
    Py_DECREF(state);
    return res;
}

static PyObject *
ImportError_repr(PyObject *self)
{
    int hasargs = PyTuple_GET_SIZE(((PyBaseExceptionObject *)self)->args) != 0;
    PyImportErrorObject *exc = PyImportErrorObject_CAST(self);
    if (exc->name == NULL && exc->path == NULL) {
        return BaseException_repr(self);
    }
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
    if (writer == NULL) {
        goto error;
    }
    PyObject *r = BaseException_repr(self);
    if (r == NULL) {
        goto error;
    }
    if (PyUnicodeWriter_WriteSubstring(
        writer, r, 0, PyUnicode_GET_LENGTH(r) - 1) < 0)
    {
        Py_DECREF(r);
        goto error;
    }
    Py_DECREF(r);
    if (exc->name) {
        if (hasargs) {
            if (PyUnicodeWriter_WriteASCII(writer, ", ", 2) < 0) {
                goto error;
            }
        }
        if (PyUnicodeWriter_Format(writer, "name=%R", exc->name) < 0) {
            goto error;
        }
        hasargs = 1;
    }
    if (exc->path) {
        if (hasargs) {
            if (PyUnicodeWriter_WriteASCII(writer, ", ", 2) < 0) {
                goto error;
            }
        }
        if (PyUnicodeWriter_Format(writer, "path=%R", exc->path) < 0) {
            goto error;
        }
    }

    if (PyUnicodeWriter_WriteChar(writer, ')') < 0) {
        goto error;
    }

    return PyUnicodeWriter_Finish(writer);

error:
    PyUnicodeWriter_Discard(writer);
    return NULL;
}

static PyMemberDef ImportError_members[] = {
    {"msg", _Py_T_OBJECT, offsetof(PyImportErrorObject, msg), 0,
        PyDoc_STR("exception message")},
    {"name", _Py_T_OBJECT, offsetof(PyImportErrorObject, name), 0,
        PyDoc_STR("module name")},
    {"path", _Py_T_OBJECT, offsetof(PyImportErrorObject, path), 0,
        PyDoc_STR("module path")},
    {"name_from", _Py_T_OBJECT, offsetof(PyImportErrorObject, name_from), 0,
        PyDoc_STR("name imported from module")},
    {NULL}  /* Sentinel */
};

static PyMethodDef ImportError_methods[] = {
    {"__reduce__", ImportError_reduce, METH_NOARGS},
    {NULL}
};

static PyTypeObject _PyExc_ImportError = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "ImportError",
    .tp_basicsize = sizeof(PyImportErrorObject),
    .tp_dealloc = ImportError_dealloc,
    .tp_repr = ImportError_repr,
    .tp_str = ImportError_str,
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    .tp_doc = PyDoc_STR(
        "Import can't find module, "
        "or can't find name in module."),
    .tp_traverse = ImportError_traverse,
    .tp_clear = ImportError_clear,
    .tp_methods = ImportError_methods,
    .tp_members = ImportError_members,
    .tp_base = &_PyExc_Exception,
    .tp_dictoffset = offsetof(PyImportErrorObject, dict),
    .tp_init = ImportError_init,
};
PyObject *PyExc_ImportError = (PyObject *)&_PyExc_ImportError;

/*
 *    ImportCycleError extends ImportError
 */

MiddlingExtendsException(PyExc_ImportError, ImportCycleError, ImportError,
                         "Import produces a cycle.");
/*
 *    ModuleNotFoundError extends ImportError
 */

MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
                         "Module not found.");

/*
 *    OSError extends Exception
 */

static inline PyOSErrorObject *
PyOSErrorObject_CAST(PyObject *self)
{
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_OSError));
    return (PyOSErrorObject *)self;
}

#ifdef MS_WINDOWS
#include "errmap.h"
#endif

/* Where a function has a single filename, such as open() or some
 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
 * called, giving a third argument which is the filename.  But, so
 * that old code using in-place unpacking doesn't break, e.g.:
 *
 * except OSError, (errno, strerror):
 *
 * we hack args so that it only contains two items.  This also
 * means we need our own __str__() which prints out the filename
 * when it was supplied.
 *
 * (If a function has two filenames, such as rename(), symlink(),
 * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
 * which allows passing in a second filename.)
 */

/* This function doesn't cleanup on error, the caller should */
static int
oserror_parse_args(PyObject **p_args,
                   PyObject **myerrno, PyObject **strerror,
                   PyObject **filename, PyObject **filename2
#ifdef MS_WINDOWS
                   , PyObject **winerror
#endif
                  )
{
    Py_ssize_t nargs;
    PyObject *args = *p_args;
#ifndef MS_WINDOWS
    /*
     * ignored on non-Windows platforms,
     * but parsed so OSError has a consistent signature
     */
    PyObject *_winerror = NULL;
    PyObject **winerror = &_winerror;
#endif /* MS_WINDOWS */

    nargs = PyTuple_GET_SIZE(args);

    if (nargs >= 2 && nargs <= 5) {
        if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
                               myerrno, strerror,
                               filename, winerror, filename2))
            return -1;
#ifdef MS_WINDOWS
        if (*winerror && PyLong_Check(*winerror)) {
            long errcode, winerrcode;
            PyObject *newargs;
            Py_ssize_t i;

            winerrcode = PyLong_AsLong(*winerror);
            if (winerrcode == -1 && PyErr_Occurred())
                return -1;
            errcode = winerror_to_errno(winerrcode);
            *myerrno = PyLong_FromLong(errcode);
            if (!*myerrno)
                return -1;
            newargs = PyTuple_New(nargs);
            if (!newargs)
                return -1;
            PyTuple_SET_ITEM(newargs, 0, *myerrno);
            for (i = 1; i < nargs; i++) {
                PyObject *val = PyTuple_GET_ITEM(args, i);
                PyTuple_SET_ITEM(newargs, i, Py_NewRef(val));
            }
            Py_DECREF(args);
            args = *p_args = newargs;
        }
#endif /* MS_WINDOWS */
    }

    return 0;
}

static int
oserror_init(PyOSErrorObject *self, PyObject **p_args,
             PyObject *myerrno, PyObject *strerror,
             PyObject *filename, PyObject *filename2
#ifdef MS_WINDOWS
             , PyObject *winerror
#endif
             )
{
    PyObject *args = *p_args;
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);

    /* self->filename will remain Py_None otherwise */
    if (filename && filename != Py_None) {
        if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
            PyNumber_Check(filename)) {
            /* BlockingIOError's 3rd argument can be the number of
             * characters written.
             */
            self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
            if (self->written == -1 && PyErr_Occurred())
                return -1;
        }
        else {
            self->filename = Py_NewRef(filename);

            if (filename2 && filename2 != Py_None) {
                self->filename2 = Py_NewRef(filename2);
            }

            if (nargs >= 2 && nargs <= 5) {
                /* filename, filename2, and winerror are removed from the args tuple
                   (for compatibility purposes, see test_exceptions.py) */
                PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
                if (!subslice)
                    return -1;

                Py_DECREF(args);  /* replacing args */
                *p_args = args = subslice;
            }
        }
    }
    self->myerrno = Py_XNewRef(myerrno);
    self->strerror = Py_XNewRef(strerror);
#ifdef MS_WINDOWS
    self->winerror = Py_XNewRef(winerror);
#endif

    /* Steals the reference to args */
    Py_XSETREF(self->args, args);
    *p_args = args = NULL;

    return 0;
}

static PyObject *
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static int
OSError_init(PyObject *self, PyObject *args, PyObject *kwds);

static int
oserror_use_init(PyTypeObject *type)
{
    /* When __init__ is defined in an OSError subclass, we want any
       extraneous argument to __new__ to be ignored.  The only reasonable
       solution, given __new__ takes a variable number of arguments,
       is to defer arg parsing and initialization to __init__.

       But when __new__ is overridden as well, it should call our __new__
       with the right arguments.

       (see http://bugs.python.org/issue12555#msg148829 )
    */
    if (type->tp_init != OSError_init && type->tp_new == OSError_new) {
        assert((PyObject *) type != PyExc_OSError);
        return 1;
    }
    return 0;
}

static PyObject *
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyOSErrorObject *self = NULL;
    PyObject *myerrno = NULL, *strerror = NULL;
    PyObject *filename = NULL, *filename2 = NULL;
#ifdef MS_WINDOWS
    PyObject *winerror = NULL;
#endif

    Py_INCREF(args);

    if (!oserror_use_init(type)) {
        if (!_PyArg_NoKeywords(type->tp_name, kwds))
            goto error;

        if (oserror_parse_args(&args, &myerrno, &strerror,
                               &filename, &filename2
#ifdef MS_WINDOWS
                               , &winerror
#endif
            ))
            goto error;

        struct _Py_exc_state *state = get_exc_state();
        if (myerrno && PyLong_Check(myerrno) &&
            state->errnomap && (PyObject *) type == PyExc_OSError) {
            PyObject *newtype;
            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
            if (newtype) {
                type = _PyType_CAST(newtype);
            }
            else if (PyErr_Occurred())
                goto error;
        }
    }

    self = (PyOSErrorObject *) type->tp_alloc(type, 0);
    if (!self)
        goto error;

    self->dict = NULL;
    self->traceback = self->cause = self->context = NULL;
    self->written = -1;

    if (!oserror_use_init(type)) {
        if (oserror_init(self, &args, myerrno, strerror, filename, filename2
#ifdef MS_WINDOWS
                         , winerror
#endif
            ))
            goto error;
    }
    else {
        self->args = PyTuple_New(0);
        if (self->args == NULL)
            goto error;
    }

    Py_XDECREF(args);
    return (PyObject *) self;

error:
    Py_XDECREF(args);
    Py_XDECREF(self);
    return NULL;
}

static int
OSError_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
    PyObject *myerrno = NULL, *strerror = NULL;
    PyObject *filename = NULL, *filename2 = NULL;
#ifdef MS_WINDOWS
    PyObject *winerror = NULL;
#endif

    if (!oserror_use_init(Py_TYPE(self)))
        /* Everything already done in OSError_new */
        return 0;

    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
        return -1;

    Py_INCREF(args);
    if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
#ifdef MS_WINDOWS
                           , &winerror
#endif
        ))
        goto error;

    if (oserror_init(self, &args, myerrno, strerror, filename, filename2
#ifdef MS_WINDOWS
                     , winerror
#endif
        ))
        goto error;

    return 0;

error:
    Py_DECREF(args);
    return -1;
}

static int
OSError_clear(PyObject *op)
{
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
    Py_CLEAR(self->myerrno);
    Py_CLEAR(self->strerror);
    Py_CLEAR(self->filename);
    Py_CLEAR(self->filename2);
#ifdef MS_WINDOWS
    Py_CLEAR(self->winerror);
#endif
    return BaseException_clear(op);
}

static void
OSError_dealloc(PyObject *self)
{
    _PyObject_GC_UNTRACK(self);
    (void)OSError_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
OSError_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
    Py_VISIT(self->myerrno);
    Py_VISIT(self->strerror);
    Py_VISIT(self->filename);
    Py_VISIT(self->filename2);
#ifdef MS_WINDOWS
    Py_VISIT(self->winerror);
#endif
    return BaseException_traverse(op, visit, arg);
}

static PyObject *
OSError_str(PyObject *op)
{
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
#define OR_NONE(x) ((x)?(x):Py_None)
#ifdef MS_WINDOWS
    /* If available, winerror has the priority over myerrno */
    if (self->winerror && self->filename) {
        if (self->filename2) {
            return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R",
                                        OR_NONE(self->winerror),
                                        OR_NONE(self->strerror),
                                        self->filename,
                                        self->filename2);
        } else {
            return PyUnicode_FromFormat("[WinError %S] %S: %R",
                                        OR_NONE(self->winerror),
                                        OR_NONE(self->strerror),
                                        self->filename);
        }
    }
    if (self->winerror && self->strerror)
        return PyUnicode_FromFormat("[WinError %S] %S",
                                    self->winerror ? self->winerror: Py_None,
                                    self->strerror ? self->strerror: Py_None);
#endif
    if (self->filename) {
        if (self->filename2) {
            return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R",
                                        OR_NONE(self->myerrno),
                                        OR_NONE(self->strerror),
                                        self->filename,
                                        self->filename2);
        } else {
            return PyUnicode_FromFormat("[Errno %S] %S: %R",
                                        OR_NONE(self->myerrno),
                                        OR_NONE(self->strerror),
                                        self->filename);
        }
    }
    if (self->myerrno && self->strerror)
        return PyUnicode_FromFormat("[Errno %S] %S",
                                    self->myerrno, self->strerror);
    return BaseException_str(op);
}

static PyObject *
OSError_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
{
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
    PyObject *args = self->args;
    PyObject *res = NULL;

    /* self->args is only the first two real arguments if there was a
     * file name given to OSError. */
    if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
        Py_ssize_t size = self->filename2 ? 5 : 3;
        args = PyTuple_New(size);
        if (!args)
            return NULL;

        PyTuple_SET_ITEM(args, 0, Py_NewRef(PyTuple_GET_ITEM(self->args, 0)));
        PyTuple_SET_ITEM(args, 1, Py_NewRef(PyTuple_GET_ITEM(self->args, 1)));
        PyTuple_SET_ITEM(args, 2, Py_NewRef(self->filename));

        if (self->filename2) {
            /*
             * This tuple is essentially used as OSError(*args).
             * So, to recreate filename2, we need to pass in
             * winerror as well.
             */
            PyTuple_SET_ITEM(args, 3, Py_NewRef(Py_None));

            /* filename2 */
            PyTuple_SET_ITEM(args, 4, Py_NewRef(self->filename2));
        }
    } else
        Py_INCREF(args);

    if (self->dict)
        res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
    else
        res = _PyTuple_FromPair((PyObject *)Py_TYPE(self), args);
    Py_DECREF(args);
    return res;
}

static PyObject *
OSError_written_get(PyObject *op, void *context)
{
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
    if (self->written == -1) {
        PyErr_SetString(PyExc_AttributeError, "characters_written");
        return NULL;
    }
    return PyLong_FromSsize_t(self->written);
}

static int
OSError_written_set(PyObject *op, PyObject *arg, void *context)
{
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
    if (arg == NULL) {
        if (self->written == -1) {
            PyErr_SetString(PyExc_AttributeError, "characters_written");
            return -1;
        }
        self->written = -1;
        return 0;
    }
    Py_ssize_t n;
    n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
    if (n == -1 && PyErr_Occurred())
        return -1;
    self->written = n;
    return 0;
}

static PyMemberDef OSError_members[] = {
    {"errno", _Py_T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
        PyDoc_STR("POSIX exception code")},
    {"strerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
        PyDoc_STR("exception strerror")},
    {"filename", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
        PyDoc_STR("exception filename")},
    {"filename2", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
        PyDoc_STR("second exception filename")},
#ifdef MS_WINDOWS
    {"winerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
        PyDoc_STR("Win32 exception code")},
#endif
    {NULL}  /* Sentinel */
};

static PyMethodDef OSError_methods[] = {
    {"__reduce__", OSError_reduce, METH_NOARGS},
    {NULL}
};

static PyGetSetDef OSError_getset[] = {
    {"characters_written", OSError_written_get,
                           OSError_written_set, NULL},
    {NULL}
};


ComplexExtendsException(PyExc_Exception, OSError,
                        OSError, OSError_new,
                        OSError_methods, OSError_members, OSError_getset,
                        OSError_str, 0,
                        "Base class for I/O related errors.");


/*
 *    Various OSError subclasses
 */
MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
                         "I/O operation would block.");
MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
                         "Connection error.");
MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
                         "Child process error.");
MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
                         "Broken pipe.");
MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
                         "Connection aborted.");
MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
                         "Connection refused.");
MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
                         "Connection reset.");
MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
                         "File already exists.");
MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
                         "File not found.");
MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
                         "Operation doesn't work on directories.");
MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
                         "Operation only works on directories.");
MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
                         "Interrupted by signal.");
MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
                         "Not enough permissions.");
MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
                         "Process not found.");
MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
                         "Timeout expired.");

/* Compatibility aliases */
PyObject *PyExc_EnvironmentError = (PyObject *)&_PyExc_OSError;  // borrowed ref
PyObject *PyExc_IOError = (PyObject *)&_PyExc_OSError;  // borrowed ref
#ifdef MS_WINDOWS
PyObject *PyExc_WindowsError = (PyObject *)&_PyExc_OSError;  // borrowed ref
#endif

/*
 *    EOFError extends Exception
 */
SimpleExtendsException(PyExc_Exception, EOFError,
                       "Read beyond end of file.");


/*
 *    RuntimeError extends Exception
 */
SimpleExtendsException(PyExc_Exception, RuntimeError,
                       "Unspecified run-time error.");

/*
 *    RecursionError extends RuntimeError
 */
SimpleExtendsException(PyExc_RuntimeError, RecursionError,
                       "Recursion limit exceeded.");

// PythonFinalizationError extends RuntimeError
SimpleExtendsException(PyExc_RuntimeError, PythonFinalizationError,
                       "Operation blocked during Python finalization.");

/*
 *    NotImplementedError extends RuntimeError
 */
SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
                       "Method or function hasn't been implemented yet.");

/*
 *    NameError extends Exception
 */

static inline PyNameErrorObject *
PyNameErrorObject_CAST(PyObject *self)
{
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_NameError));
    return (PyNameErrorObject *)self;
}

static int
NameError_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"name", NULL};
    PyObject *name = NULL;

    if (BaseException_init(op, args, NULL) == -1) {
        return -1;
    }

    PyObject *empty_tuple = PyTuple_New(0);
    if (!empty_tuple) {
        return -1;
    }
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
                                     &name)) {
        Py_DECREF(empty_tuple);
        return -1;
    }
    Py_DECREF(empty_tuple);

    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
    Py_XSETREF(self->name, Py_XNewRef(name));

    return 0;
}

static int
NameError_clear(PyObject *op)
{
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
    Py_CLEAR(self->name);
    return BaseException_clear(op);
}

static void
NameError_dealloc(PyObject *self)
{
    _PyObject_GC_UNTRACK(self);
    (void)NameError_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
NameError_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
    Py_VISIT(self->name);
    return BaseException_traverse(op, visit, arg);
}

static PyMemberDef NameError_members[] = {
        {"name", _Py_T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
        {NULL}  /* Sentinel */
};

static PyMethodDef NameError_methods[] = {
        {NULL}  /* Sentinel */
};

ComplexExtendsException(PyExc_Exception, NameError,
                        NameError, 0,
                        NameError_methods, NameError_members,
                        0, BaseException_str, 0, "Name not found globally.");

/*
 *    UnboundLocalError extends NameError
 */

MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
                       "Local name referenced but not bound to a value.");

/*
 *    AttributeError extends Exception
 */

static inline PyAttributeErrorObject *
PyAttributeErrorObject_CAST(PyObject *self)
{
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_AttributeError));
    return (PyAttributeErrorObject *)self;
}

static int
AttributeError_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"name", "obj", NULL};
    PyObject *name = NULL;
    PyObject *obj = NULL;

    if (BaseException_init(op, args, NULL) == -1) {
        return -1;
    }

    PyObject *empty_tuple = PyTuple_New(0);
    if (!empty_tuple) {
        return -1;
    }
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
                                     &name, &obj)) {
        Py_DECREF(empty_tuple);
        return -1;
    }
    Py_DECREF(empty_tuple);

    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
    Py_XSETREF(self->name, Py_XNewRef(name));
    Py_XSETREF(self->obj, Py_XNewRef(obj));

    return 0;
}

static int
AttributeError_clear(PyObject *op)
{
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
    Py_CLEAR(self->obj);
    Py_CLEAR(self->name);
    return BaseException_clear(op);
}

static void
AttributeError_dealloc(PyObject *self)
{
    _PyObject_GC_UNTRACK(self);
    (void)AttributeError_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
AttributeError_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
    Py_VISIT(self->obj);
    Py_VISIT(self->name);
    return BaseException_traverse(op, visit, arg);
}

/* Pickling support */
static PyObject *
AttributeError_getstate(PyObject *op, PyObject *Py_UNUSED(ignored))
{
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
    PyObject *dict = self->dict;
    if (self->name || self->args) {
        dict = dict ? PyDict_Copy(dict) : PyDict_New();
        if (dict == NULL) {
            return NULL;
        }
        if (self->name && PyDict_SetItemString(dict, "name", self->name) < 0) {
            Py_DECREF(dict);
            return NULL;
        }
        /* We specifically are not pickling the obj attribute since there are many
        cases where it is unlikely to be picklable. See GH-103352.
        */
        if (self->args && PyDict_SetItemString(dict, "args", self->args) < 0) {
            Py_DECREF(dict);
            return NULL;
        }
        return dict;
    }
    else if (dict) {
        return Py_NewRef(dict);
    }
    Py_RETURN_NONE;
}

static PyObject *
AttributeError_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
{
    PyObject *state = AttributeError_getstate(op, NULL);
    if (state == NULL) {
        return NULL;
    }

    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
    PyObject *return_value = PyTuple_Pack(3, Py_TYPE(self), self->args, state);
    Py_DECREF(state);
    return return_value;
}

static PyMemberDef AttributeError_members[] = {
    {"name", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
    {"obj", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
    {NULL}  /* Sentinel */
};

static PyMethodDef AttributeError_methods[] = {
    {"__getstate__", AttributeError_getstate, METH_NOARGS},
    {"__reduce__", AttributeError_reduce, METH_NOARGS },
    {NULL}
};

ComplexExtendsException(PyExc_Exception, AttributeError,
                        AttributeError, 0,
                        AttributeError_methods, AttributeError_members,
                        0, BaseException_str, 0, "Attribute not found.");

/*
 *    SyntaxError extends Exception
 */

static inline PySyntaxErrorObject *
PySyntaxErrorObject_CAST(PyObject *self)
{
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_SyntaxError));
    return (PySyntaxErrorObject *)self;
}

static int
SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
{
    PyObject *info = NULL;
    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);

    if (BaseException_init(op, args, kwds) == -1)
        return -1;

    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
    if (lenargs >= 1) {
        Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0)));
    }
    if (lenargs == 2) {
        info = PyTuple_GET_ITEM(args, 1);
        info = PySequence_Tuple(info);
        if (!info) {
            return -1;
        }

        PyObject *filename, *lineno, *offset, *text;
        PyObject *end_lineno = NULL;
        PyObject *end_offset = NULL;
        PyObject *metadata = NULL;
        if (!PyArg_ParseTuple(info, "OOOO|OOO",
                              &filename, &lineno,
                              &offset, &text,
                              &end_lineno, &end_offset, &metadata)) {
            Py_DECREF(info);
            return -1;
        }

        Py_XSETREF(self->filename, Py_NewRef(filename));
        Py_XSETREF(self->lineno, Py_NewRef(lineno));
        Py_XSETREF(self->offset, Py_NewRef(offset));
        Py_XSETREF(self->text, Py_NewRef(text));
        Py_XSETREF(self->end_lineno, Py_XNewRef(end_lineno));
        Py_XSETREF(self->end_offset, Py_XNewRef(end_offset));
        Py_XSETREF(self->metadata, Py_XNewRef(metadata));
        Py_DECREF(info);

        if (self->end_lineno != NULL && self->end_offset == NULL) {
            PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
            return -1;
        }
    }
    return 0;
}

static int
SyntaxError_clear(PyObject *op)
{
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
    Py_CLEAR(self->msg);
    Py_CLEAR(self->filename);
    Py_CLEAR(self->lineno);
    Py_CLEAR(self->offset);
    Py_CLEAR(self->end_lineno);
    Py_CLEAR(self->end_offset);
    Py_CLEAR(self->text);
    Py_CLEAR(self->print_file_and_line);
    Py_CLEAR(self->metadata);
    return BaseException_clear(op);
}

static void
SyntaxError_dealloc(PyObject *self)
{
    _PyObject_GC_UNTRACK(self);
    (void)SyntaxError_clear(self);
    Py_TYPE(self)->tp_free(self);
}

static int
SyntaxError_traverse(PyObject *op, visitproc visit, void *arg)
{
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
    Py_VISIT(self->msg);
    Py_VISIT(self->filename);
    Py_VISIT(self->lineno);
    Py_VISIT(self->offset);
    Py_VISIT(self->end_lineno);
    Py_VISIT(self->end_offset);
    Py_VISIT(self->text);
    Py_VISIT(self->print_file_and_line);
    Py_VISIT(self->metadata);
    return BaseException_traverse(op, visit, arg);
}

/* This is called "my_basename" instead of just "basename" to avoid name
   conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
   defined, and Python does define that. */
static PyObject*
my_basename(PyObject *name)
{
    Py_ssize_t i, size, offset;
    int kind;
    const void *data;

    kind = PyUnicode_KIND(name);
    data = PyUnicode_DATA(name);
    size = PyUnicode_GET_LENGTH(name);
    offset = 0;
    for(i=0; i < size; i++) {
        if (PyUnicode_READ(kind, data, i) == SEP) {
            offset = i + 1;
        }
    }
    if (offset != 0) {
        return PyUnicode_Substring(name, offset, size);
    }
    else {
        return Py_NewRef(name);
    }
}


static PyObject *
SyntaxError_str(PyObject *op)
{
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
    int have_lineno = 0;
    PyObject *filename;
    PyObject *result;
    /* Below, we always ignore overflow errors, just printing -1.
       Still, we cannot allow an OverflowError to be raised, so
       we need to call PyLong_AsLongAndOverflow. */
    int overflow;

    /* XXX -- do all the additional formatting with filename and
       lineno here */

    if (self->filename && PyUnicode_Check(self->filename)) {
        filename = my_basename(self->filename);
        if (filename == NULL)
            return NULL;
    } else {
        filename = NULL;
    }
    have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);

    if (!filename && !have_lineno)
        return PyObject_Str(self->msg ? self->msg : Py_None);

    // Even if 'filename' can be an instance of a subclass of 'str',
    // we only render its "true" content and do not use str(filename).
    if (filename && have_lineno)
        result = PyUnicode_FromFormat("%S (%U, line %ld)",
                   self->msg ? self->msg : Py_None,
                   filename,
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
    else if (filename)
        result = PyUnicode_FromFormat("%S (%U)",
                   self->msg ? self->msg : Py_None,
                   filename);
    else /* only have_lineno */
        result = PyUnicode_FromFormat("%S (line %ld)",
                   self->msg ? self->msg : Py_None,
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
    Py_XDECREF(filename);
    return result;
}

static PyMemberDef SyntaxError_members[] = {
    {"msg", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
        PyDoc_STR("exception msg")},
    {"filename", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
        PyDoc_STR("exception filename")},
    {"lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
        PyDoc_STR("exception lineno")},
    {"offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
        PyDoc_STR("exception offset")},
    {"text", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
        PyDoc_STR("exception text")},
    {"end_lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
                   PyDoc_STR("exception end lineno")},
    {"end_offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
                   PyDoc_STR("exception end offset")},
    {"print_file_and_line", _Py_T_OBJECT,
        offsetof(PySyntaxErrorObject, print_file_and_line), 0,
        PyDoc_STR("exception print_file_and_line")},
    {"_metadata", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, metadata), 0,
                   PyDoc_STR("exception private metadata")},
    {NULL}  /* Sentinel */
};

ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
                        0, 0, SyntaxError_members, 0,
                        SyntaxError_str, 0, "Invalid syntax.");


/*
 *    IndentationError extends SyntaxError
 */
MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
                         "Improper indentation.");


/*
 *    TabError extends IndentationError
 */
MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
                         "Improper mixture of spaces and tabs.");

/*
 *    IncompleteInputError extends SyntaxError
 */
MiddlingExtendsExceptionEx(PyExc_SyntaxError, IncompleteInputError, _IncompleteInputError,
                           SyntaxError, "incomplete input.");

/*
 *    LookupError extends Exception
 */
SimpleExtendsException(PyExc_Exception, LookupError,
                       "Base class for lookup errors.");


/*
 *    IndexError extends LookupError
 */
SimpleExtendsException(PyExc_LookupError, IndexError,
                       "Sequence index out of range.");


/*
 *    KeyError extends LookupError
 */

static PyObject *
KeyError_str(PyObject *op)
{
    /* If args is a tuple of exactly one item, apply repr to args[0].
       This is done so that e.g. the exception raised by {}[''] prints
         KeyError: ''
       rather than the confusing
         KeyError
       alone.  The downside is that if KeyError is raised with an explanatory
       string, that string will be displayed in quotes.  Too bad.
       If args is anything else, use the default BaseException__str__().
    */
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
    if (PyTuple_GET_SIZE(self->args) == 1) {
        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
    }
    return BaseException_str(op);
}

ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
                        0, 0, 0, 0, KeyError_str, 0, "Mapping key not found.");


/*
 *    ValueError extends Exception
 */
SimpleExtendsException(PyExc_Exception, ValueError,
                       "Inappropriate argument value (of correct type).");

/*
 *    UnicodeError extends ValueError
 */

SimpleExtendsException(PyExc_ValueError, UnicodeError,
                       "Unicode related error.");


/*
 * Check the validity of 'attr' as a unicode or bytes object depending
 * on 'as_bytes'.
 *
 * The 'name' is the attribute name and is only used for error reporting.
 *
 * On success, this returns 0.
 * On failure, this sets a TypeError and returns -1.
 */
static int
check_unicode_error_attribute(PyObject *attr, const char *name, int as_bytes)
{
    assert(as_bytes == 0 || as_bytes == 1);
    if (attr == NULL) {
        PyErr_Format(PyExc_TypeError,
                     "UnicodeError '%s' attribute is not set",
                     name);
        return -1;
    }
    if (!(as_bytes ? PyBytes_Check(attr) : PyUnicode_Check(attr))) {
        PyErr_Format(PyExc_TypeError,
                     "UnicodeError '%s' attribute must be a %s",
                     name, as_bytes ? "bytes" : "string");
        return -1;
    }
    return 0;
}


/*
 * Check the validity of 'attr' as a unicode or bytes object depending
 * on 'as_bytes' and return a new reference on it if it is the case.
 *
 * The 'name' is the attribute name and is only used for error reporting.
 *
 * On success, this returns a strong reference on 'attr'.
 * On failure, this sets a TypeError and returns NULL.
 */
static PyObject *
as_unicode_error_attribute(PyObject *attr, const char *name, int as_bytes)
{
    int rc = check_unicode_error_attribute(attr, name, as_bytes);
    return rc < 0 ? NULL : Py_NewRef(attr);
}


#define PyUnicodeError_Check(PTR)   \
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
#define PyUnicodeError_CAST(PTR)    \
    (assert(PyUnicodeError_Check(PTR)), ((PyUnicodeErrorObject *)(PTR)))


/* class names to use when reporting errors */
#define Py_UNICODE_ENCODE_ERROR_NAME        "UnicodeEncodeError"
#define Py_UNICODE_DECODE_ERROR_NAME        "UnicodeDecodeError"
#define Py_UNICODE_TRANSLATE_ERROR_NAME     "UnicodeTranslateError"


/*
 * Check that 'self' is a UnicodeError object.
 *
 * On success, this returns 0.
 * On failure, this sets a TypeError exception and returns -1.
 *
 * The 'expect_type' is the name of the expected type, which is
 * only used for error reporting.
 *
 * As an implementation detail, the `PyUnicode*Error_*` functions
 * currently allow *any* subclass of UnicodeError as 'self'.
 *
 * Use one of the `Py_UNICODE_*_ERROR_NAME` macros to avoid typos.
 */
static inline int
check_unicode_error_type(PyObject *self, const char *expect_type)
{
    assert(self != NULL);
    if (!PyUnicodeError_Check(self)) {
        PyErr_Format(PyExc_TypeError,
                     "expecting a %s object, got %T", expect_type, self);
        return -1;
    }
    return 0;
}


// --- PyUnicodeEncodeObject: internal helpers --------------------------------
//
// In the helpers below, the caller is responsible to ensure that 'self'
// is a PyUnicodeErrorObject, although this is verified on DEBUG builds
// through PyUnicodeError_CAST().

/*
 * Return the underlying (str) 'encoding' attribute of a UnicodeError object.
 */
static inline PyObject *
unicode_error_get_encoding_impl(PyObject *self)
{
    assert(self != NULL);
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
    return as_unicode_error_attribute(exc->encoding, "encoding", false);
}


/*
 * Return the underlying 'object' attribute of a UnicodeError object
 * as a bytes or a string instance, depending on the 'as_bytes' flag.
 */
static inline PyObject *
unicode_error_get_object_impl(PyObject *self, int as_bytes)
{
    assert(self != NULL);
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
    return as_unicode_error_attribute(exc->object, "object", as_bytes);
}


/*
 * Return the underlying (str) 'reason' attribute of a UnicodeError object.
 */
static inline PyObject *
unicode_error_get_reason_impl(PyObject *self)
{
    assert(self != NULL);
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
    return as_unicode_error_attribute(exc->reason, "reason", false);
}


/*
 * Set the underlying (str) 'reason' attribute of a UnicodeError object.
 *
 * Return 0 on success and -1 on failure.
 */
static inline int
unicode_error_set_reason_impl(PyObject *self, const char *reason)
{
    assert(self != NULL);
    PyObject *value = PyUnicode_FromString(reason);
    if (value == NULL) {
        return -1;
    }
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
    Py_XSETREF(exc->reason, value);
    return 0;
}


/*
 * Set the 'start' attribute of a UnicodeError object.
 *
 * Return 0 on success and -1 on failure.
 */
static inline int
unicode_error_set_start_impl(PyObject *self, Py_ssize_t start)
{
    assert(self != NULL);
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
    exc->start = start;
    return 0;
}


/*
 * Set the 'end' attribute of a UnicodeError object.
 *
 * Return 0 on success and -1 on failure.
 */
static inline int
unicode_error_set_end_impl(PyObject *self, Py_ssize_t end)
{
    assert(self != NULL);
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
    exc->end = end;
    return 0;
}

// --- PyUnicodeEncodeObject: internal getters --------------------------------

/*
 * Adjust the (inclusive) 'start' value of a UnicodeError object.
 *
 * The 'start' can be negative or not, but when adjusting the value,
 * we clip it in [0, max(0, objlen - 1)] and do not interpret it as
 * a relative offset.
 *
 * This function always succeeds.
 */
static Py_ssize_t
unicode_error_adjust_start(Py_ssize_t start, Py_ssize_t objlen)
{
    assert(objlen >= 0);
    if (start < 0) {
        start = 0;
    }
    if (start >= objlen) {
        start = objlen == 0 ? 0 : objlen - 1;
    }
    return start;
}


/* Assert some properties of the adjusted 'start' value. */
#ifndef NDEBUG
static void
assert_adjusted_unicode_error_start(Py_ssize_t start, Py_ssize_t objlen)
{
    assert(objlen >= 0);
    /* in the future, `min_start` may be something else */
    Py_ssize_t min_start = 0;
    assert(start >= min_start);
    /* in the future, `max_start` may be something else */
    Py_ssize_t max_start = Py_MAX(min_start, objlen - 1);
    assert(start <= max_start);
}
#else
#define assert_adjusted_unicode_error_start(...)
#endif


/*
 * Adjust the (exclusive) 'end' value of a UnicodeError object.
 *
 * The 'end' can be negative or not, but when adjusting the value,
 * we clip it in [min(1, objlen), max(min(1, objlen), objlen)] and
 * do not interpret it as a relative offset.
 *
 * This function always succeeds.
 */
static Py_ssize_t
unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen)
{
    assert(objlen >= 0);
    if (end < 1) {
        end = 1;
    }
    if (end > objlen) {
        end = objlen;
    }
    return end;
}

#define PyUnicodeError_Check(PTR)   \
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
#define PyUnicodeErrorObject_CAST(op)   \
    (assert(PyUnicodeError_Check(op)), ((PyUnicodeErrorObject *)(op)))

/* Assert some properties of the adjusted 'end' value. */
#ifndef NDEBUG
static void
assert_adjusted_unicode_error_end(Py_ssize_t end, Py_ssize_t objlen)
{
    assert(objlen >= 0);
    /* in the future, `min_end` may be something else */
    Py_ssize_t min_end = Py_MIN(1, objlen);
    assert(end >= min_end);
    /* in the future, `max_end` may be something else */
    Py_ssize_t max_end = Py_MAX(min_end, objlen);
    assert(end <= max_end);
}
#else
#define assert_adjusted_unicode_error_end(...)
#endif


/*
 * Adjust the length of the range described by a UnicodeError object.
 *
 * The 'start' and 'end' arguments must have been obtained by
 * unicode_error_adjust_start() and unicode_error_adjust_end().
 *
 * The result is clipped in [0, objlen]. By construction, it
 * will always be smaller than 'objlen' as 'start' and 'end'
 * are smaller than 'objlen'.
 */
static Py_ssize_t
unicode_error_adjust_len(Py_ssize_t start, Py_ssize_t end, Py_ssize_t objlen)
{
    assert_adjusted_unicode_error_start(start, objlen);
    assert_adjusted_unicode_error_end(end, objlen);
    Py_ssize_t ranlen = end - start;
    assert(ranlen <= objlen);
    return ranlen < 0 ? 0 : ranlen;
}


/* Assert some properties of the adjusted range 'len' value. */
#ifndef NDEBUG
static void
assert_adjusted_unicode_error_len(Py_ssize_t ranlen, Py_ssize_t objlen)
{
    assert(objlen >= 0);
    assert(ranlen >= 0);
    assert(ranlen <= objlen);
}
#else
#define assert_adjusted_unicode_error_len(...)
#endif


/*
 * Get various common parameters of a UnicodeError object.
 *
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
 * although this condition is verified by this function on DEBUG builds.
 *
 * Return 0 on success and -1 on failure.
 *
 * Output parameters:
 *
 *     obj          A strong reference to the 'object' attribute.
 *     objlen       The 'object' length.
 *     start        The clipped 'start' attribute.
 *     end          The clipped 'end' attribute.
 *     slen         The length of the slice described by the clipped 'start'
 *                  and 'end' values. It always lies in [0, objlen].
 *
 * An output parameter can be NULL to indicate that
 * the corresponding value does not need to be stored.
 *
 * Input parameter:
 *
 *     as_bytes     If true, the error's 'object' attribute must be a `bytes`,
 *                  i.e. 'self' is a `UnicodeDecodeError` instance. Otherwise,
 *                  the 'object' attribute must be a string.
 *
 *                  A TypeError is raised if the 'object' type is incompatible.
 */
int
_PyUnicodeError_GetParams(PyObject *self,
                          PyObject **obj, Py_ssize_t *objlen,
                          Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t *slen,
                          int as_bytes)
{
    assert(self != NULL);
    assert(as_bytes == 0 || as_bytes == 1);
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
    PyObject *r = as_unicode_error_attribute(exc->object, "object", as_bytes);
    if (r == NULL) {
        return -1;
    }

    Py_ssize_t n = as_bytes ? PyBytes_GET_SIZE(r) : PyUnicode_GET_LENGTH(r);
    if (objlen != NULL) {
        *objlen = n;
    }

    Py_ssize_t start_value = -1;
    if (start != NULL || slen != NULL) {
        start_value = unicode_error_adjust_start(exc->start, n);
    }
    if (start != NULL) {
        assert_adjusted_unicode_error_start(start_value, n);
        *start = start_value;
    }

    Py_ssize_t end_value = -1;
    if (end != NULL || slen != NULL) {
        end_value = unicode_error_adjust_end(exc->end, n);
    }
    if (end != NULL) {
        assert_adjusted_unicode_error_end(end_value, n);
        *end = end_value;
    }

    if (slen != NULL) {
        *slen = unicode_error_adjust_len(start_value, end_value, n);
        assert_adjusted_unicode_error_len(*slen, n);
    }

    if (obj != NULL) {
        *obj = r;
    }
    else {
        Py_DECREF(r);
    }
    return 0;
}


// --- PyUnicodeEncodeObject: 'encoding' getters ------------------------------
// Note: PyUnicodeTranslateError does not have an 'encoding' attribute.

PyObject *
PyUnicodeEncodeError_GetEncoding(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_encoding_impl(self);
}


PyObject *
PyUnicodeDecodeError_GetEncoding(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_encoding_impl(self);
}


// --- PyUnicodeEncodeObject: 'object' getters --------------------------------

PyObject *
PyUnicodeEncodeError_GetObject(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, false);
}


PyObject *
PyUnicodeDecodeError_GetObject(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, true);
}


PyObject *
PyUnicodeTranslateError_GetObject(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, false);
}


// --- PyUnicodeEncodeObject: 'start' getters ---------------------------------

/*
 * Specialization of _PyUnicodeError_GetParams() for the 'start' attribute.
 *
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
 * although this condition is verified by this function on DEBUG builds.
 */
static inline int
unicode_error_get_start_impl(PyObject *self, Py_ssize_t *start, int as_bytes)
{
    assert(self != NULL);
    return _PyUnicodeError_GetParams(self, NULL, NULL,
                                     start, NULL, NULL,
                                     as_bytes);
}


int
PyUnicodeEncodeError_GetStart(PyObject *self, Py_ssize_t *start)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, false);
}


int
PyUnicodeDecodeError_GetStart(PyObject *self, Py_ssize_t *start)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, true);
}


int
PyUnicodeTranslateError_GetStart(PyObject *self, Py_ssize_t *start)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, false);
}


// --- PyUnicodeEncodeObject: 'start' setters ---------------------------------

int
PyUnicodeEncodeError_SetStart(PyObject *self, Py_ssize_t start)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
}


int
PyUnicodeDecodeError_SetStart(PyObject *self, Py_ssize_t start)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
}


int
PyUnicodeTranslateError_SetStart(PyObject *self, Py_ssize_t start)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
}


// --- PyUnicodeEncodeObject: 'end' getters -----------------------------------

/*
 * Specialization of _PyUnicodeError_GetParams() for the 'end' attribute.
 *
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
 * although this condition is verified by this function on DEBUG builds.
 */
static inline int
unicode_error_get_end_impl(PyObject *self, Py_ssize_t *end, int as_bytes)
{
    assert(self != NULL);
    return _PyUnicodeError_GetParams(self, NULL, NULL,
                                     NULL, end, NULL,
                                     as_bytes);
}


int
PyUnicodeEncodeError_GetEnd(PyObject *self, Py_ssize_t *end)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, false);
}


int
PyUnicodeDecodeError_GetEnd(PyObject *self, Py_ssize_t *end)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, true);
}


int
PyUnicodeTranslateError_GetEnd(PyObject *self, Py_ssize_t *end)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, false);
}


// --- PyUnicodeEncodeObject: 'end' setters -----------------------------------

int
PyUnicodeEncodeError_SetEnd(PyObject *self, Py_ssize_t end)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
}


int
PyUnicodeDecodeError_SetEnd(PyObject *self, Py_ssize_t end)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
}


int
PyUnicodeTranslateError_SetEnd(PyObject *self, Py_ssize_t end)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
}


// --- PyUnicodeEncodeObject: 'reason' getters --------------------------------

PyObject *
PyUnicodeEncodeError_GetReason(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
}


PyObject *
PyUnicodeDecodeError_GetReason(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
}


PyObject *
PyUnicodeTranslateError_GetReason(PyObject *self)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
}


// --- PyUnicodeEncodeObject: 'reason' setters --------------------------------

int
PyUnicodeEncodeError_SetReason(PyObject *self, const char *reason)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
}


int
PyUnicodeDecodeError_SetReason(PyObject *self, const char *reason)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
}


int
PyUnicodeTranslateError_SetReason(PyObject *self, const char *reason)
{
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
}


static int
UnicodeError_clear(PyObject *self)
{
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    Py_CLEAR(exc->encoding);
    Py_CLEAR(exc->object);
    Py_CLEAR(exc->reason);
    return BaseException_clear(self);
}

static void
UnicodeError_dealloc(PyObject *self)
{
    PyTypeObject *type = Py_TYPE(self);
    _PyObject_GC_UNTRACK(self);
    (void)UnicodeError_clear(self);
    type->tp_free(self);
}

static int
UnicodeError_traverse(PyObject *self, visitproc visit, void *arg)
{
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    Py_VISIT(exc->encoding);
    Py_VISIT(exc->object);
    Py_VISIT(exc->reason);
    return BaseException_traverse(self, visit, arg);
}

static PyMemberDef UnicodeError_members[] = {
    {"encoding", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
        PyDoc_STR("exception encoding")},
    {"object", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
        PyDoc_STR("exception object")},
    {"start", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
        PyDoc_STR("exception start")},
    {"end", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
        PyDoc_STR("exception end")},
    {"reason", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
        PyDoc_STR("exception reason")},
    {NULL}  /* Sentinel */
};


/*
 *    UnicodeEncodeError extends UnicodeError
 */

static int
UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    if (BaseException_init(self, args, kwds) == -1) {
        return -1;
    }

    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
    Py_ssize_t start = -1, end = -1;

    if (!PyArg_ParseTuple(args, "UUnnU",
                          &encoding, &object, &start, &end, &reason))
    {
        return -1;
    }

    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
    Py_XSETREF(exc->object, Py_NewRef(object));
    exc->start = start;
    exc->end = end;
    Py_XSETREF(exc->reason, Py_NewRef(reason));
    return 0;
}

static PyObject *
UnicodeEncodeError_str(PyObject *self)
{
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    PyObject *result = NULL;
    PyObject *reason_str = NULL;
    PyObject *encoding_str = NULL;

    if (exc->object == NULL) {
        /* Not properly initialized. */
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
    }

    /* Get reason and encoding as strings, which they might not be if
       they've been modified after we were constructed. */
    reason_str = PyObject_Str(exc->reason);
    if (reason_str == NULL) {
        goto done;
    }
    encoding_str = PyObject_Str(exc->encoding);
    if (encoding_str == NULL) {
        goto done;
    }
    // calls to PyObject_Str(...) above might mutate 'exc->object'
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
        goto done;
    }
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
    Py_ssize_t start = exc->start, end = exc->end;

    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
        const char *fmt;
        if (badchar <= 0xff) {
            fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
        }
        else if (badchar <= 0xffff) {
            fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
        }
        else {
            fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
        }
        result = PyUnicode_FromFormat(
            fmt,
            encoding_str,
            (int)badchar,
            start,
            reason_str);
    }
    else {
        result = PyUnicode_FromFormat(
            "'%U' codec can't encode characters in position %zd-%zd: %U",
            encoding_str,
            start,
            end - 1,
            reason_str);
    }
done:
    Py_XDECREF(reason_str);
    Py_XDECREF(encoding_str);
    return result;
}

static PyTypeObject _PyExc_UnicodeEncodeError = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "UnicodeEncodeError",
    sizeof(PyUnicodeErrorObject), 0,
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    UnicodeEncodeError_str, 0, 0, 0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    PyDoc_STR("Unicode encoding error."), UnicodeError_traverse,
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
    UnicodeEncodeError_init, 0, BaseException_new,
};
PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;


/*
 *    UnicodeDecodeError extends UnicodeError
 */

static int
UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    if (BaseException_init(self, args, kwds) == -1) {
        return -1;
    }

    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
    Py_ssize_t start = -1, end = -1;

    if (!PyArg_ParseTuple(args, "UOnnU",
                          &encoding, &object, &start, &end, &reason))
    {
        return -1;
    }

    if (PyBytes_Check(object)) {
        Py_INCREF(object);  // make 'object' a strong reference
    }
    else {
        Py_buffer view;
        if (PyObject_GetBuffer(object, &view, PyBUF_SIMPLE) != 0) {
            return -1;
        }
        // 'object' is borrowed, so we can re-use the variable
        object = PyBytes_FromStringAndSize(view.buf, view.len);
        PyBuffer_Release(&view);
        if (object == NULL) {
            return -1;
        }
    }

    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
    Py_XSETREF(exc->object, object /* already a strong reference */);
    exc->start = start;
    exc->end = end;
    Py_XSETREF(exc->reason, Py_NewRef(reason));
    return 0;
}

static PyObject *
UnicodeDecodeError_str(PyObject *self)
{
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    PyObject *result = NULL;
    PyObject *reason_str = NULL;
    PyObject *encoding_str = NULL;

    if (exc->object == NULL) {
        /* Not properly initialized. */
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
    }

    /* Get reason and encoding as strings, which they might not be if
       they've been modified after we were constructed. */
    reason_str = PyObject_Str(exc->reason);
    if (reason_str == NULL) {
        goto done;
    }
    encoding_str = PyObject_Str(exc->encoding);
    if (encoding_str == NULL) {
        goto done;
    }
    // calls to PyObject_Str(...) above might mutate 'exc->object'
    if (check_unicode_error_attribute(exc->object, "object", true) < 0) {
        goto done;
    }
    Py_ssize_t len = PyBytes_GET_SIZE(exc->object);
    Py_ssize_t start = exc->start, end = exc->end;

    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
        int badbyte = (int)(PyBytes_AS_STRING(exc->object)[start] & 0xff);
        result = PyUnicode_FromFormat(
            "'%U' codec can't decode byte 0x%02x in position %zd: %U",
            encoding_str,
            badbyte,
            start,
            reason_str);
    }
    else {
        result = PyUnicode_FromFormat(
            "'%U' codec can't decode bytes in position %zd-%zd: %U",
            encoding_str,
            start,
            end - 1,
            reason_str);
    }
done:
    Py_XDECREF(reason_str);
    Py_XDECREF(encoding_str);
    return result;
}

static PyTypeObject _PyExc_UnicodeDecodeError = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "UnicodeDecodeError",
    sizeof(PyUnicodeErrorObject), 0,
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    UnicodeDecodeError_str, 0, 0, 0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    PyDoc_STR("Unicode decoding error."), UnicodeError_traverse,
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
    UnicodeDecodeError_init, 0, BaseException_new,
};
PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;

PyObject *
PyUnicodeDecodeError_Create(
    const char *encoding, const char *object, Py_ssize_t length,
    Py_ssize_t start, Py_ssize_t end, const char *reason)
{
    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
                                 encoding, object, length, start, end, reason);
}


/*
 *    UnicodeTranslateError extends UnicodeError
 */

static int
UnicodeTranslateError_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    if (BaseException_init(self, args, kwds) == -1) {
        return -1;
    }

    PyObject *object = NULL, *reason = NULL;  // borrowed
    Py_ssize_t start = -1, end = -1;

    if (!PyArg_ParseTuple(args, "UnnU", &object, &start, &end, &reason)) {
        return -1;
    }

    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    Py_XSETREF(exc->object, Py_NewRef(object));
    exc->start = start;
    exc->end = end;
    Py_XSETREF(exc->reason, Py_NewRef(reason));
    return 0;
}


static PyObject *
UnicodeTranslateError_str(PyObject *self)
{
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
    PyObject *result = NULL;
    PyObject *reason_str = NULL;

    if (exc->object == NULL) {
        /* Not properly initialized. */
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
    }

    /* Get reason as a string, which it might not be if it's been
       modified after we were constructed. */
    reason_str = PyObject_Str(exc->reason);
    if (reason_str == NULL) {
        goto done;
    }
    // call to PyObject_Str(...) above might mutate 'exc->object'
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
        goto done;
    }
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
    Py_ssize_t start = exc->start, end = exc->end;

    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
        const char *fmt;
        if (badchar <= 0xff) {
            fmt = "can't translate character '\\x%02x' in position %zd: %U";
        }
        else if (badchar <= 0xffff) {
            fmt = "can't translate character '\\u%04x' in position %zd: %U";
        }
        else {
            fmt = "can't translate character '\\U%08x' in position %zd: %U";
        }
        result = PyUnicode_FromFormat(
            fmt,
            (int)badchar,
            start,
            reason_str);
    }
    else {
        result = PyUnicode_FromFormat(
            "can't translate characters in position %zd-%zd: %U",
            start,
            end - 1,
            reason_str);
    }
done:
    Py_XDECREF(reason_str);
    return result;
}

static PyTypeObject _PyExc_UnicodeTranslateError = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "UnicodeTranslateError",
    sizeof(PyUnicodeErrorObject), 0,
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    UnicodeTranslateError_str, 0, 0, 0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    PyDoc_STR("Unicode translation error."), UnicodeError_traverse,
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
    UnicodeTranslateError_init, 0, BaseException_new,
};
PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;

PyObject *
_PyUnicodeTranslateError_Create(
    PyObject *object,
    Py_ssize_t start, Py_ssize_t end, const char *reason)
{
    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
                                 object, start, end, reason);
}

/*
 *    AssertionError extends Exception
 */
SimpleExtendsException(PyExc_Exception, AssertionError,
                       "Assertion failed.");


/*
 *    ArithmeticError extends Exception
 */
SimpleExtendsException(PyExc_Exception, ArithmeticError,
                       "Base class for arithmetic errors.");


/*
 *    FloatingPointError extends ArithmeticError
 */
SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
                       "Floating-point operation failed.");


/*
 *    OverflowError extends ArithmeticError
 */
SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
                       "Result too large to be represented.");


/*
 *    ZeroDivisionError extends ArithmeticError
 */
SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
          "Second argument to a division or modulo operation was zero.");


/*
 *    SystemError extends Exception
 */
SimpleExtendsException(PyExc_Exception, SystemError,
    "Internal error in the Python interpreter.\n"
    "\n"
    "Please report this to the Python maintainer, along with the traceback,\n"
    "the Python version, and the hardware/OS platform and version.");


/*
 *    ReferenceError extends Exception
 */
SimpleExtendsException(PyExc_Exception, ReferenceError,
                       "Weak ref proxy used after referent went away.");


/*
 *    MemoryError extends Exception
 */

#define MEMERRORS_SAVE 16

#ifdef Py_GIL_DISABLED
# define MEMERRORS_LOCK(state) PyMutex_LockFlags(&state->memerrors_lock, _Py_LOCK_DONT_DETACH)
# define MEMERRORS_UNLOCK(state) PyMutex_Unlock(&state->memerrors_lock)
#else
# define MEMERRORS_LOCK(state) ((void)0)
# define MEMERRORS_UNLOCK(state) ((void)0)
#endif

static PyObject *
get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds)
{
    PyBaseExceptionObject *self = NULL;
    struct _Py_exc_state *state = get_exc_state();

    MEMERRORS_LOCK(state);
    if (state->memerrors_freelist != NULL) {
        /* Fetch MemoryError from freelist and initialize it */
        self = state->memerrors_freelist;
        state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
        state->memerrors_numfree--;
        self->dict = NULL;
        self->args = (PyObject *)&_Py_SINGLETON(tuple_empty);
        _Py_NewReference((PyObject *)self);
        _PyObject_GC_TRACK(self);
    }
    MEMERRORS_UNLOCK(state);

    if (self != NULL) {
        return (PyObject *)self;
    }

    if (!allow_allocation) {
        PyInterpreterState *interp = _PyInterpreterState_GET();
        return Py_NewRef(
            &_Py_INTERP_SINGLETON(interp, last_resort_memory_error));
    }
    return BaseException_new((PyTypeObject *)PyExc_MemoryError, args, kwds);
}

static PyObject *
MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* If this is a subclass of MemoryError, don't use the freelist
     * and just return a fresh object */
    if (type != (PyTypeObject *) PyExc_MemoryError) {
        return BaseException_new(type, args, kwds);
    }
    return get_memory_error(1, args, kwds);
}

PyObject *
_PyErr_NoMemory(PyThreadState *tstate)
{
    if (Py_IS_TYPE(PyExc_MemoryError, NULL)) {
        /* PyErr_NoMemory() has been called before PyExc_MemoryError has been
           initialized by _PyExc_Init() */
        Py_FatalError("Out of memory and PyExc_MemoryError is not "
                      "initialized yet");
    }
    PyObject *err = get_memory_error(0, NULL, NULL);
    if (err != NULL) {
        _PyErr_SetRaisedException(tstate, err);
    }
    return NULL;
}

static void
MemoryError_dealloc(PyObject *op)
{
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
    _PyObject_GC_UNTRACK(self);

    (void)BaseException_clear(op);

    /* If this is a subclass of MemoryError, we don't need to
     * do anything in the free-list*/
    if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
        Py_TYPE(self)->tp_free(op);
        return;
    }

    struct _Py_exc_state *state = get_exc_state();
    MEMERRORS_LOCK(state);
    if (state->memerrors_numfree < MEMERRORS_SAVE) {
        self->dict = (PyObject *) state->memerrors_freelist;
        state->memerrors_freelist = self;
        state->memerrors_numfree++;
        MEMERRORS_UNLOCK(state);
        return;
    }
    MEMERRORS_UNLOCK(state);

    Py_TYPE(self)->tp_free((PyObject *)self);
}

static int
preallocate_memerrors(void)
{
    /* We create enough MemoryErrors and then decref them, which will fill
       up the freelist. */
    int i;

    PyObject *errors[MEMERRORS_SAVE];
    for (i = 0; i < MEMERRORS_SAVE; i++) {
        errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
                                    NULL, NULL);
        if (!errors[i]) {
            return -1;
        }
    }
    for (i = 0; i < MEMERRORS_SAVE; i++) {
        Py_DECREF(errors[i]);
    }
    return 0;
}

static void
free_preallocated_memerrors(struct _Py_exc_state *state)
{
    while (state->memerrors_freelist != NULL) {
        PyObject *self = (PyObject *) state->memerrors_freelist;
        state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
        Py_TYPE(self)->tp_free(self);
    }
}


PyTypeObject _PyExc_MemoryError = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "MemoryError",
    sizeof(PyBaseExceptionObject),
    0, MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    PyDoc_STR("Out of memory."), BaseException_traverse,
    BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
    0, 0, 0, offsetof(PyBaseExceptionObject, dict),
    BaseException_init, 0, MemoryError_new
};
PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;


/*
 *    BufferError extends Exception
 */
SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");


/* Warning category docstrings */

/*
 *    Warning extends Exception
 */
SimpleExtendsException(PyExc_Exception, Warning,
                       "Base class for warning categories.");


/*
 *    UserWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, UserWarning,
                       "Base class for warnings generated by user code.");


/*
 *    DeprecationWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, DeprecationWarning,
                       "Base class for warnings about deprecated features.");


/*
 *    PendingDeprecationWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
    "Base class for warnings about features which will be deprecated\n"
    "in the future.");


/*
 *    SyntaxWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, SyntaxWarning,
                       "Base class for warnings about dubious syntax.");


/*
 *    RuntimeWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, RuntimeWarning,
                 "Base class for warnings about dubious runtime behavior.");


/*
 *    FutureWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, FutureWarning,
    "Base class for warnings about constructs that will change semantically\n"
    "in the future.");


/*
 *    ImportWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, ImportWarning,
          "Base class for warnings about probable mistakes in module imports");


/*
 *    UnicodeWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, UnicodeWarning,
    "Base class for warnings about Unicode related problems, mostly\n"
    "related to conversion problems.");


/*
 *    BytesWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, BytesWarning,
    "Base class for warnings about bytes and buffer related problems, mostly\n"
    "related to conversion from str or comparing to str.");


/*
 *    EncodingWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, EncodingWarning,
    "Base class for warnings about encodings.");


/*
 *    ResourceWarning extends Warning
 */
SimpleExtendsException(PyExc_Warning, ResourceWarning,
    "Base class for warnings about resource usage.");



#ifdef MS_WINDOWS
#include <winsock2.h>
/* The following constants were added to errno.h in VS2010 but have
   preferred WSA equivalents. */
#undef EADDRINUSE
#undef EADDRNOTAVAIL
#undef EAFNOSUPPORT
#undef EALREADY
#undef ECONNABORTED
#undef ECONNREFUSED
#undef ECONNRESET
#undef EDESTADDRREQ
#undef EHOSTUNREACH
#undef EINPROGRESS
#undef EISCONN
#undef ELOOP
#undef EMSGSIZE
#undef ENETDOWN
#undef ENETRESET
#undef ENETUNREACH
#undef ENOBUFS
#undef ENOPROTOOPT
#undef ENOTCONN
#undef ENOTSOCK
#undef EOPNOTSUPP
#undef EPROTONOSUPPORT
#undef EPROTOTYPE
#undef EWOULDBLOCK

#if defined(WSAEALREADY) && !defined(EALREADY)
#define EALREADY WSAEALREADY
#endif
#if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
#define ECONNABORTED WSAECONNABORTED
#endif
#if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
#define ECONNREFUSED WSAECONNREFUSED
#endif
#if defined(WSAECONNRESET) && !defined(ECONNRESET)
#define ECONNRESET WSAECONNRESET
#endif
#if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
#define EINPROGRESS WSAEINPROGRESS
#endif
#if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
#define ESHUTDOWN WSAESHUTDOWN
#endif
#if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
#define EWOULDBLOCK WSAEWOULDBLOCK
#endif
#endif /* MS_WINDOWS */

struct static_exception {
    PyTypeObject *exc;
    const char *name;
};

static struct static_exception static_exceptions[] = {
#define ITEM(NAME) {&_PyExc_##NAME, #NAME}
    // Level 1
    ITEM(BaseException),

    // Level 2: BaseException subclasses
    ITEM(BaseExceptionGroup),
    ITEM(Exception),
    ITEM(GeneratorExit),
    ITEM(KeyboardInterrupt),
    ITEM(SystemExit),

    // Level 3: Exception(BaseException) subclasses
    ITEM(ArithmeticError),
    ITEM(AssertionError),
    ITEM(AttributeError),
    ITEM(BufferError),
    ITEM(EOFError),
    //ITEM(ExceptionGroup),
    ITEM(ImportError),
    ITEM(LookupError),
    ITEM(MemoryError),
    ITEM(NameError),
    ITEM(OSError),
    ITEM(ReferenceError),
    ITEM(RuntimeError),
    ITEM(StopAsyncIteration),
    ITEM(StopIteration),
    ITEM(SyntaxError),
    ITEM(SystemError),
    ITEM(TypeError),
    ITEM(ValueError),
    ITEM(Warning),

    // Level 4: ArithmeticError(Exception) subclasses
    ITEM(FloatingPointError),
    ITEM(OverflowError),
    ITEM(ZeroDivisionError),

    // Level 4: Warning(Exception) subclasses
    ITEM(BytesWarning),
    ITEM(DeprecationWarning),
    ITEM(EncodingWarning),
    ITEM(FutureWarning),
    ITEM(ImportWarning),
    ITEM(PendingDeprecationWarning),
    ITEM(ResourceWarning),
    ITEM(RuntimeWarning),
    ITEM(SyntaxWarning),
    ITEM(UnicodeWarning),
    ITEM(UserWarning),

    // Level 4: OSError(Exception) subclasses
    ITEM(BlockingIOError),
    ITEM(ChildProcessError),
    ITEM(ConnectionError),
    ITEM(FileExistsError),
    ITEM(FileNotFoundError),
    ITEM(InterruptedError),
    ITEM(IsADirectoryError),
    ITEM(NotADirectoryError),
    ITEM(PermissionError),
    ITEM(ProcessLookupError),
    ITEM(TimeoutError),

    // Level 4: Other subclasses
    ITEM(IndentationError), // base: SyntaxError(Exception)
    {&_PyExc_IncompleteInputError, "_IncompleteInputError"}, // base: SyntaxError(Exception)
    ITEM(IndexError),  // base: LookupError(Exception)
    ITEM(KeyError),  // base: LookupError(Exception)
    ITEM(ImportCycleError), // base: ImportError(Exception)
    ITEM(ModuleNotFoundError), // base: ImportError(Exception)
    ITEM(NotImplementedError),  // base: RuntimeError(Exception)
    ITEM(PythonFinalizationError),  // base: RuntimeError(Exception)
    ITEM(RecursionError),  // base: RuntimeError(Exception)
    ITEM(UnboundLocalError), // base: NameError(Exception)
    ITEM(UnicodeError),  // base: ValueError(Exception)

    // Level 5: ConnectionError(OSError) subclasses
    ITEM(BrokenPipeError),
    ITEM(ConnectionAbortedError),
    ITEM(ConnectionRefusedError),
    ITEM(ConnectionResetError),

    // Level 5: IndentationError(SyntaxError) subclasses
    ITEM(TabError),  // base: IndentationError

    // Level 5: UnicodeError(ValueError) subclasses
    ITEM(UnicodeDecodeError),
    ITEM(UnicodeEncodeError),
    ITEM(UnicodeTranslateError),
#undef ITEM
};


int
_PyExc_InitTypes(PyInterpreterState *interp)
{
    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
        PyTypeObject *exc = static_exceptions[i].exc;
        if (_PyStaticType_InitBuiltin(interp, exc) < 0) {
            return -1;
        }
        if (exc->tp_new == BaseException_new
            && exc->tp_init == BaseException_init)
        {
            exc->tp_vectorcall = BaseException_vectorcall;
        }
    }
    return 0;
}


static void
_PyExc_FiniTypes(PyInterpreterState *interp)
{
    for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
        PyTypeObject *exc = static_exceptions[i].exc;
        _PyStaticType_FiniBuiltin(interp, exc);
    }
}


PyStatus
_PyExc_InitGlobalObjects(PyInterpreterState *interp)
{
    if (preallocate_memerrors() < 0) {
        return _PyStatus_NO_MEMORY();
    }
    return _PyStatus_OK();
}

PyStatus
_PyExc_InitState(PyInterpreterState *interp)
{
    struct _Py_exc_state *state = &interp->exc_state;

#define ADD_ERRNO(TYPE, CODE) \
    do { \
        PyObject *_code = PyLong_FromLong(CODE); \
        assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
        if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
            Py_XDECREF(_code); \
            return _PyStatus_ERR("errmap insertion problem."); \
        } \
        Py_DECREF(_code); \
    } while (0)

    /* Add exceptions to errnomap */
    assert(state->errnomap == NULL);
    state->errnomap = PyDict_New();
    if (!state->errnomap) {
        return _PyStatus_NO_MEMORY();
    }

    ADD_ERRNO(BlockingIOError, EAGAIN);
    ADD_ERRNO(BlockingIOError, EALREADY);
    ADD_ERRNO(BlockingIOError, EINPROGRESS);
    ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
    ADD_ERRNO(BrokenPipeError, EPIPE);
#ifdef ESHUTDOWN
    ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
#endif
    ADD_ERRNO(ChildProcessError, ECHILD);
    ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
    ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
    ADD_ERRNO(ConnectionResetError, ECONNRESET);
    ADD_ERRNO(FileExistsError, EEXIST);
    ADD_ERRNO(FileNotFoundError, ENOENT);
    ADD_ERRNO(IsADirectoryError, EISDIR);
    ADD_ERRNO(NotADirectoryError, ENOTDIR);
    ADD_ERRNO(InterruptedError, EINTR);
    ADD_ERRNO(PermissionError, EACCES);
    ADD_ERRNO(PermissionError, EPERM);
#ifdef ENOTCAPABLE
    // Extension for WASI capability-based security. Process lacks
    // capability to access a resource.
    ADD_ERRNO(PermissionError, ENOTCAPABLE);
#endif
    ADD_ERRNO(ProcessLookupError, ESRCH);
    ADD_ERRNO(TimeoutError, ETIMEDOUT);
#ifdef WSAETIMEDOUT
    ADD_ERRNO(TimeoutError, WSAETIMEDOUT);
#endif

    return _PyStatus_OK();

#undef ADD_ERRNO
}


/* Add exception types to the builtins module */
int
_PyBuiltins_AddExceptions(PyObject *bltinmod)
{
    PyObject *mod_dict = PyModule_GetDict(bltinmod);
    if (mod_dict == NULL) {
        return -1;
    }

    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
        struct static_exception item = static_exceptions[i];

        if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
            return -1;
        }
    }

    PyObject *PyExc_ExceptionGroup = create_exception_group_class();
    if (!PyExc_ExceptionGroup) {
        return -1;
    }
    if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
        return -1;
    }
    if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) {
        return -1;
    }
    if (PyDict_SetItemString(mod_dict, "IOError", PyExc_OSError)) {
        return -1;
    }
#ifdef MS_WINDOWS
    if (PyDict_SetItemString(mod_dict, "WindowsError", PyExc_OSError)) {
        return -1;
    }
#endif
    return 0;
}

void
_PyExc_ClearExceptionGroupType(PyInterpreterState *interp)
{
    struct _Py_exc_state *state = &interp->exc_state;
    Py_CLEAR(state->PyExc_ExceptionGroup);
}

void
_PyExc_Fini(PyInterpreterState *interp)
{
    struct _Py_exc_state *state = &interp->exc_state;
    free_preallocated_memerrors(state);
    Py_CLEAR(state->errnomap);

    _PyExc_FiniTypes(interp);
}

int
_PyException_AddNote(PyObject *exc, PyObject *note)
{
    if (!PyExceptionInstance_Check(exc)) {
        PyErr_Format(PyExc_TypeError,
                     "exc must be an exception, not '%s'",
                     Py_TYPE(exc)->tp_name);
        return -1;
    }
    PyObject *r = BaseException_add_note(exc, note);
    int res = r == NULL ? -1 : 0;
    Py_XDECREF(r);
    return res;
}
