diff options
Diffstat (limited to 'c/call_python.c')
-rw-r--r-- | c/call_python.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/c/call_python.c b/c/call_python.c index 8fdcb90..d3d2e17 100644 --- a/c/call_python.c +++ b/c/call_python.c @@ -1,10 +1,18 @@ #if PY_VERSION_HEX >= 0x03080000 -# define Py_BUILD_CORE -/* for access to the fields of PyInterpreterState */ -# include "internal/pycore_pystate.h" -# undef Py_BUILD_CORE +# define HAVE_PYINTERPSTATE_GETDICT #endif + +static PyObject *_current_interp_key(void) +{ + PyInterpreterState *interp = PyThreadState_GET()->interp; +#ifdef HAVE_PYINTERPSTATE_GETDICT + return PyInterpreterState_GetDict(interp); /* shared reference */ +#else + return interp->modules; +#endif +} + static PyObject *_get_interpstate_dict(void) { /* Hack around to return a dict that is subinterpreter-local. @@ -14,8 +22,9 @@ static PyObject *_get_interpstate_dict(void) */ static PyObject *attr_name = NULL; PyThreadState *tstate; - PyObject *d, *builtins; + PyObject *d, *interpdict; int err; + PyInterpreterState *interp; tstate = PyThreadState_GET(); if (tstate == NULL) { @@ -23,8 +32,13 @@ static PyObject *_get_interpstate_dict(void) return NULL; } - builtins = tstate->interp->builtins; - if (builtins == NULL) { + interp = tstate->interp; +#ifdef HAVE_PYINTERPSTATE_GETDICT + interpdict = PyInterpreterState_GetDict(interp); /* shared reference */ +#else + interpdict = interp->builtins; +#endif + if (interpdict == NULL) { /* subinterpreter was cleared already, or is being cleared right now, to a point that is too much for us to continue */ return NULL; @@ -38,13 +52,13 @@ static PyObject *_get_interpstate_dict(void) goto error; } - d = PyDict_GetItem(builtins, attr_name); + d = PyDict_GetItem(interpdict, attr_name); if (d == NULL) { d = PyDict_New(); if (d == NULL) goto error; - err = PyDict_SetItem(builtins, attr_name, d); - Py_DECREF(d); /* if successful, there is one ref left in builtins */ + err = PyDict_SetItem(interpdict, attr_name, d); + Py_DECREF(d); /* if successful, there is one ref left in interpdict */ if (err < 0) goto error; } @@ -163,7 +177,7 @@ static int _update_cache_to_call_python(struct _cffi_externpy_s *externpy) if (infotuple == NULL) return 3; /* no ffi.def_extern() from this subinterpreter */ - new1 = PyThreadState_GET()->interp->modules; + new1 = _current_interp_key(); Py_INCREF(new1); Py_INCREF(infotuple); old1 = (PyObject *)externpy->reserved1; @@ -252,7 +266,7 @@ static void cffi_call_python(struct _cffi_externpy_s *externpy, char *args) } else { PyGILState_STATE state = gil_ensure(); - if (externpy->reserved1 != PyThreadState_GET()->interp->modules) { + if (externpy->reserved1 != _current_interp_key()) { /* Update the (reserved1, reserved2) cache. This will fail if we didn't call @ffi.def_extern() in this particular subinterpreter. */ |