diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2019-03-15 23:47:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-15 23:47:43 (GMT) |
commit | d2fdd1fedf6b9dc785cf5025b548a989faed089a (patch) | |
tree | fad1d8a72d9dea315758219cd5f1122ba0d0a87a | |
parent | c11183cdcff6af13c4339fdcce84ab63f7930ddc (diff) | |
download | cpython-d2fdd1fedf6b9dc785cf5025b548a989faed089a.zip cpython-d2fdd1fedf6b9dc785cf5025b548a989faed089a.tar.gz cpython-d2fdd1fedf6b9dc785cf5025b548a989faed089a.tar.bz2 |
bpo-36124: Add PyInterpreterState.dict. (gh-12132)
-rw-r--r-- | Doc/c-api/init.rst | 12 | ||||
-rw-r--r-- | Include/internal/pycore_pystate.h | 2 | ||||
-rw-r--r-- | Include/pystate.h | 10 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst | 4 | ||||
-rw-r--r-- | Python/pystate.c | 14 |
5 files changed, 40 insertions, 2 deletions
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 6b5290a..2c6d21f 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1026,6 +1026,18 @@ All of the following functions must be called after :c:func:`Py_Initialize`. .. versionadded:: 3.7 +.. c:function:: PyObject* PyInterpreterState_GetDict(PyInterpreterState *interp) + + Return a dictionary in which interpreter-specific data may be stored. + If this function returns *NULL* then no exception has been raised and + the caller should assume no interpreter-specific dict is available. + + This is not a replacement for :c:func:`PyModule_GetState()`, which + extensions should use to store interpreter-specific state information. + + .. versionadded:: 3.8 + + .. c:function:: PyObject* PyThreadState_GetDict() Return a dictionary in which extensions can store thread-specific state diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 945d992..703a85b 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -63,6 +63,8 @@ struct _is { int dlopenflags; #endif + PyObject *dict; /* Stores per-interpreter state */ + PyObject *builtins_copy; PyObject *import_func; /* Initialized to PyEval_EvalFrameDefault(). */ diff --git a/Include/pystate.h b/Include/pystate.h index a79a2e6..4c25e3f 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -24,17 +24,23 @@ typedef struct _ts PyThreadState; /* struct _is is defined in internal/pycore_pystate.h */ typedef struct _is PyInterpreterState; -/* State unique per thread */ - PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03080000 +/* New in 3.8 */ +PyAPI_FUNC(PyObject *) PyInterpreterState_GetDict(PyInterpreterState *); +#endif + #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 /* New in 3.7 */ PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 + +/* State unique per thread */ + /* New in 3.3 */ PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*); PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*); diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst new file mode 100644 index 0000000..ee9b0c1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst @@ -0,0 +1,4 @@ +Add a new interpreter-specific dict and expose it in the C-API via +PyInterpreterState_GetDict(). This parallels PyThreadState_GetDict(). +However, extension modules should continue using PyModule_GetState() for +their own internal per-interpreter state. diff --git a/Python/pystate.c b/Python/pystate.c index cdf5a69..6a2dc10 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -224,6 +224,7 @@ PyInterpreterState_Clear(PyInterpreterState *interp) Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->importlib); Py_CLEAR(interp->import_func); + Py_CLEAR(interp->dict); #ifdef HAVE_FORK Py_CLEAR(interp->before_forkers); Py_CLEAR(interp->after_forkers_parent); @@ -462,6 +463,19 @@ _PyInterpreterState_GetMainModule(PyInterpreterState *interp) return PyMapping_GetItemString(interp->modules, "__main__"); } +PyObject * +PyInterpreterState_GetDict(PyInterpreterState *interp) +{ + if (interp->dict == NULL) { + interp->dict = PyDict_New(); + if (interp->dict == NULL) { + PyErr_Clear(); + } + } + /* Returning NULL means no per-interpreter dict is available. */ + return interp->dict; +} + /* Default implementation for _PyThreadState_GetFrame */ static struct _frame * threadstate_getframe(PyThreadState *self) |