
static void
_ensure_current_cause(PyThreadState *tstate, PyObject *cause)
{
    if (cause == NULL) {
        return;
    }
    PyObject *exc = _PyErr_GetRaisedException(tstate);
    assert(exc != NULL);
    assert(PyException_GetCause(exc) == NULL);
    PyException_SetCause(exc, Py_NewRef(cause));
    _PyErr_SetRaisedException(tstate, exc);
}


/* InterpreterError extends Exception */

static PyTypeObject _PyExc_InterpreterError = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "concurrent.interpreters.InterpreterError",
    .tp_doc = PyDoc_STR("A cross-interpreter operation failed"),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    //.tp_traverse = ((PyTypeObject *)PyExc_Exception)->tp_traverse,
    //.tp_clear = ((PyTypeObject *)PyExc_Exception)->tp_clear,
    //.tp_base = (PyTypeObject *)PyExc_Exception,
};
PyObject *PyExc_InterpreterError = (PyObject *)&_PyExc_InterpreterError;

/* InterpreterNotFoundError extends InterpreterError */

static PyTypeObject _PyExc_InterpreterNotFoundError = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "concurrent.interpreters.InterpreterNotFoundError",
    .tp_doc = PyDoc_STR("An interpreter was not found"),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    //.tp_traverse = ((PyTypeObject *)PyExc_Exception)->tp_traverse,
    //.tp_clear = ((PyTypeObject *)PyExc_Exception)->tp_clear,
    .tp_base = &_PyExc_InterpreterError,
};
PyObject *PyExc_InterpreterNotFoundError = (PyObject *)&_PyExc_InterpreterNotFoundError;

/* NotShareableError extends TypeError */

static int
_init_notshareableerror(exceptions_t *state)
{
    const char *name = "concurrent.interpreters.NotShareableError";
    PyObject *base = PyExc_TypeError;
    PyObject *ns = NULL;
    PyObject *exctype = PyErr_NewException(name, base, ns);
    if (exctype == NULL) {
        return -1;
    }
    state->PyExc_NotShareableError = exctype;
    return 0;
}

static void
_fini_notshareableerror(exceptions_t *state)
{
    Py_CLEAR(state->PyExc_NotShareableError);
}

static PyObject *
get_notshareableerror_type(PyThreadState *tstate)
{
    _PyXI_state_t *local = _PyXI_GET_STATE(tstate->interp);
    if (local == NULL) {
        PyErr_Clear();
        return NULL;
    }
    return local->exceptions.PyExc_NotShareableError;
}

static void
_ensure_notshareableerror(PyThreadState *tstate,
                          PyObject *cause, int force, PyObject *msgobj)
{
    PyObject *ctx = _PyErr_GetRaisedException(tstate);
    PyObject *exctype = get_notshareableerror_type(tstate);
    if (exctype != NULL) {
        if (!force && ctx != NULL && Py_TYPE(ctx) == (PyTypeObject *)exctype) {
            // A NotShareableError instance is already set.
            assert(cause == NULL);
            _PyErr_SetRaisedException(tstate, ctx);
        }
    }
    else {
        exctype = PyExc_TypeError;
    }
    _PyErr_SetObject(tstate, exctype, msgobj);
    // We have to set the context manually since _PyErr_SetObject() doesn't.
    _PyErr_ChainExceptions1Tstate(tstate, ctx);
    _ensure_current_cause(tstate, cause);
}

static void
set_notshareableerror(PyThreadState *tstate, PyObject *cause, int force, const char *msg)
{
    PyObject *msgobj = PyUnicode_FromString(msg);
    if (msgobj == NULL) {
        assert(_PyErr_Occurred(tstate));
    }
    else {
        _ensure_notshareableerror(tstate, cause, force, msgobj);
        Py_DECREF(msgobj);
    }
}

static void
format_notshareableerror_v(PyThreadState *tstate, PyObject *cause, int force,
                           const char *format, va_list vargs)
{
    PyObject *msgobj = PyUnicode_FromFormatV(format, vargs);
    if (msgobj == NULL) {
        assert(_PyErr_Occurred(tstate));
    }
    else {
        _ensure_notshareableerror(tstate, cause, force, msgobj);
        Py_DECREF(msgobj);
    }
}

static void
format_notshareableerror(PyThreadState *tstate, PyObject *cause, int force,
                         const char *format, ...)
{
    va_list vargs;
    va_start(vargs, format);
    format_notshareableerror_v(tstate, cause, force, format, vargs);
    va_end(vargs);
}


/* lifecycle */

static int
init_static_exctypes(exceptions_t *state, PyInterpreterState *interp)
{
    assert(state == &_PyXI_GET_STATE(interp)->exceptions);
    PyTypeObject *base = (PyTypeObject *)PyExc_Exception;

    // PyExc_InterpreterError
    _PyExc_InterpreterError.tp_base = base;
    _PyExc_InterpreterError.tp_traverse = base->tp_traverse;
    _PyExc_InterpreterError.tp_clear = base->tp_clear;
    if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterError) < 0) {
        goto error;
    }
    state->PyExc_InterpreterError = (PyObject *)&_PyExc_InterpreterError;

    // PyExc_InterpreterNotFoundError
    _PyExc_InterpreterNotFoundError.tp_traverse = base->tp_traverse;
    _PyExc_InterpreterNotFoundError.tp_clear = base->tp_clear;
    if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterNotFoundError) < 0) {
        goto error;
    }
    state->PyExc_InterpreterNotFoundError =
            (PyObject *)&_PyExc_InterpreterNotFoundError;

    return 0;

error:
    fini_static_exctypes(state, interp);
    return -1;
}

static void
fini_static_exctypes(exceptions_t *state, PyInterpreterState *interp)
{
    assert(state == &_PyXI_GET_STATE(interp)->exceptions);
    if (state->PyExc_InterpreterNotFoundError != NULL) {
        state->PyExc_InterpreterNotFoundError = NULL;
        _PyStaticType_FiniBuiltin(interp, &_PyExc_InterpreterNotFoundError);
    }
    if (state->PyExc_InterpreterError != NULL) {
        state->PyExc_InterpreterError = NULL;
        _PyStaticType_FiniBuiltin(interp, &_PyExc_InterpreterError);
    }
}

static int
init_heap_exctypes(exceptions_t *state)
{
    if (_init_notshareableerror(state) < 0) {
        goto error;
    }
    return 0;

error:
    fini_heap_exctypes(state);
    return -1;
}

static void
fini_heap_exctypes(exceptions_t *state)
{
    _fini_notshareableerror(state);
}
