summaryrefslogtreecommitdiffstats
path: root/Python/crossinterp_exceptions.h
diff options
context:
space:
mode:
Diffstat (limited to 'Python/crossinterp_exceptions.h')
-rw-r--r--Python/crossinterp_exceptions.h125
1 files changed, 114 insertions, 11 deletions
diff --git a/Python/crossinterp_exceptions.h b/Python/crossinterp_exceptions.h
index 3cb45d2..3999364 100644
--- a/Python/crossinterp_exceptions.h
+++ b/Python/crossinterp_exceptions.h
@@ -1,4 +1,25 @@
+static void
+_ensure_current_cause(PyThreadState *tstate, PyObject *cause)
+{
+ if (cause == NULL) {
+ return;
+ }
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
+ assert(exc != NULL);
+ PyObject *ctx = PyException_GetContext(exc);
+ if (ctx == NULL) {
+ PyException_SetContext(exc, Py_NewRef(cause));
+ }
+ else {
+ Py_DECREF(ctx);
+ }
+ assert(PyException_GetCause(exc) == NULL);
+ PyException_SetCause(exc, Py_NewRef(cause));
+ _PyErr_SetRaisedException(tstate, exc);
+}
+
+
/* InterpreterError extends Exception */
static PyTypeObject _PyExc_InterpreterError = {
@@ -25,6 +46,97 @@ static PyTypeObject _PyExc_InterpreterNotFoundError = {
};
PyObject *PyExc_InterpreterNotFoundError = (PyObject *)&_PyExc_InterpreterNotFoundError;
+/* NotShareableError extends ValueError */
+
+static int
+_init_notshareableerror(exceptions_t *state)
+{
+ const char *name = "interpreters.NotShareableError";
+ // XXX Inherit from TypeError.
+ PyObject *base = PyExc_ValueError;
+ 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_ValueError;
+ }
+ _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);
+ }
+}
+
+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);
+ }
+}
+
+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 */
@@ -76,18 +188,9 @@ fini_static_exctypes(exceptions_t *state, PyInterpreterState *interp)
static int
init_heap_exctypes(exceptions_t *state)
{
- PyObject *exctype;
-
- /* NotShareableError extends ValueError */
- const char *name = "interpreters.NotShareableError";
- PyObject *base = PyExc_ValueError;
- PyObject *ns = NULL;
- exctype = PyErr_NewException(name, base, ns);
- if (exctype == NULL) {
+ if (_init_notshareableerror(state) < 0) {
goto error;
}
- state->PyExc_NotShareableError = exctype;
-
return 0;
error:
@@ -98,5 +201,5 @@ error:
static void
fini_heap_exctypes(exceptions_t *state)
{
- Py_CLEAR(state->PyExc_NotShareableError);
+ _fini_notshareableerror(state);
}