summaryrefslogtreecommitdiffstats
path: root/Python/crossinterp_exceptions.h
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2024-02-13 21:56:49 (GMT)
committerGitHub <noreply@github.com>2024-02-13 21:56:49 (GMT)
commit514b1c91b8651e8ab9129a34b7482033d2fd4e5b (patch)
tree11a091856f2b7f3ec65009b5b9de4e424a2a79bc /Python/crossinterp_exceptions.h
parent206f73dc5f1b4c3c81119808aa7fd9038661cf90 (diff)
downloadcpython-514b1c91b8651e8ab9129a34b7482033d2fd4e5b.zip
cpython-514b1c91b8651e8ab9129a34b7482033d2fd4e5b.tar.gz
cpython-514b1c91b8651e8ab9129a34b7482033d2fd4e5b.tar.bz2
gh-76785: Improved Subinterpreters Compatibility with 3.12 (gh-115424)
For the most part, these changes make is substantially easier to backport subinterpreter-related code to 3.12, especially the related modules (e.g. _xxsubinterpreters). The main motivation is to support releasing a PyPI package with the 3.13 capabilities compiled for 3.12. A lot of the changes here involve either hiding details behind macros/functions or splitting up some files.
Diffstat (limited to 'Python/crossinterp_exceptions.h')
-rw-r--r--Python/crossinterp_exceptions.h80
1 files changed, 80 insertions, 0 deletions
diff --git a/Python/crossinterp_exceptions.h b/Python/crossinterp_exceptions.h
new file mode 100644
index 0000000..e418cf9
--- /dev/null
+++ b/Python/crossinterp_exceptions.h
@@ -0,0 +1,80 @@
+
+/* InterpreterError extends Exception */
+
+static PyTypeObject _PyExc_InterpreterError = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "interpreters.InterpreterError",
+ .tp_doc = PyDoc_STR("A cross-interpreter operation failed"),
+ //.tp_base = (PyTypeObject *)PyExc_BaseException,
+};
+PyObject *PyExc_InterpreterError = (PyObject *)&_PyExc_InterpreterError;
+
+/* InterpreterNotFoundError extends InterpreterError */
+
+static PyTypeObject _PyExc_InterpreterNotFoundError = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "interpreters.InterpreterNotFoundError",
+ .tp_doc = PyDoc_STR("An interpreter was not found"),
+ .tp_base = &_PyExc_InterpreterError,
+};
+PyObject *PyExc_InterpreterNotFoundError = (PyObject *)&_PyExc_InterpreterNotFoundError;
+
+/* NotShareableError extends ValueError */
+
+static int
+_init_not_shareable_error_type(PyInterpreterState *interp)
+{
+ const char *name = "interpreters.NotShareableError";
+ PyObject *base = PyExc_ValueError;
+ PyObject *ns = NULL;
+ PyObject *exctype = PyErr_NewException(name, base, ns);
+ if (exctype == NULL) {
+ return -1;
+ }
+
+ _PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError = exctype;
+ return 0;
+}
+
+static void
+_fini_not_shareable_error_type(PyInterpreterState *interp)
+{
+ Py_CLEAR(_PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError);
+}
+
+static PyObject *
+_get_not_shareable_error_type(PyInterpreterState *interp)
+{
+ assert(_PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError != NULL);
+ return _PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError;
+}
+
+
+/* lifecycle */
+
+static int
+init_exceptions(PyInterpreterState *interp)
+{
+ // builtin static types
+ _PyExc_InterpreterError.tp_base = (PyTypeObject *)PyExc_BaseException;
+ if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterError) < 0) {
+ return -1;
+ }
+ if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterNotFoundError) < 0) {
+ return -1;
+ }
+
+ // heap types
+ // We would call _init_not_shareable_error_type() here too,
+ // but that leads to ref leaks
+
+ return 0;
+}
+
+static void
+fini_exceptions(PyInterpreterState *interp)
+{
+ // Likewise with _fini_not_shareable_error_type().
+ _PyStaticType_Dealloc(interp, &_PyExc_InterpreterNotFoundError);
+ _PyStaticType_Dealloc(interp, &_PyExc_InterpreterError);
+}