Skip to content

Commit d2fdd1f

Browse files
bpo-36124: Add PyInterpreterState.dict. (gh-12132)
1 parent c11183c commit d2fdd1f

File tree

5 files changed

+40
-2
lines changed

5 files changed

+40
-2
lines changed

Doc/c-api/init.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,18 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
10261026
.. versionadded:: 3.7
10271027
10281028
1029+
.. c:function:: PyObject* PyInterpreterState_GetDict(PyInterpreterState *interp)
1030+
1031+
Return a dictionary in which interpreter-specific data may be stored.
1032+
If this function returns *NULL* then no exception has been raised and
1033+
the caller should assume no interpreter-specific dict is available.
1034+
1035+
This is not a replacement for :c:func:`PyModule_GetState()`, which
1036+
extensions should use to store interpreter-specific state information.
1037+
1038+
.. versionadded:: 3.8
1039+
1040+
10291041
.. c:function:: PyObject* PyThreadState_GetDict()
10301042
10311043
Return a dictionary in which extensions can store thread-specific state

Include/internal/pycore_pystate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ struct _is {
6363
int dlopenflags;
6464
#endif
6565

66+
PyObject *dict; /* Stores per-interpreter state */
67+
6668
PyObject *builtins_copy;
6769
PyObject *import_func;
6870
/* Initialized to PyEval_EvalFrameDefault(). */

Include/pystate.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,23 @@ typedef struct _ts PyThreadState;
2424
/* struct _is is defined in internal/pycore_pystate.h */
2525
typedef struct _is PyInterpreterState;
2626

27-
/* State unique per thread */
28-
2927
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
3028
PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
3129
PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
3230

31+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03080000
32+
/* New in 3.8 */
33+
PyAPI_FUNC(PyObject *) PyInterpreterState_GetDict(PyInterpreterState *);
34+
#endif
35+
3336
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
3437
/* New in 3.7 */
3538
PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *);
3639
#endif
3740
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
41+
42+
/* State unique per thread */
43+
3844
/* New in 3.3 */
3945
PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*);
4046
PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Add a new interpreter-specific dict and expose it in the C-API via
2+
PyInterpreterState_GetDict(). This parallels PyThreadState_GetDict().
3+
However, extension modules should continue using PyModule_GetState() for
4+
their own internal per-interpreter state.

Python/pystate.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
224224
Py_CLEAR(interp->builtins_copy);
225225
Py_CLEAR(interp->importlib);
226226
Py_CLEAR(interp->import_func);
227+
Py_CLEAR(interp->dict);
227228
#ifdef HAVE_FORK
228229
Py_CLEAR(interp->before_forkers);
229230
Py_CLEAR(interp->after_forkers_parent);
@@ -462,6 +463,19 @@ _PyInterpreterState_GetMainModule(PyInterpreterState *interp)
462463
return PyMapping_GetItemString(interp->modules, "__main__");
463464
}
464465

466+
PyObject *
467+
PyInterpreterState_GetDict(PyInterpreterState *interp)
468+
{
469+
if (interp->dict == NULL) {
470+
interp->dict = PyDict_New();
471+
if (interp->dict == NULL) {
472+
PyErr_Clear();
473+
}
474+
}
475+
/* Returning NULL means no per-interpreter dict is available. */
476+
return interp->dict;
477+
}
478+
465479
/* Default implementation for _PyThreadState_GetFrame */
466480
static struct _frame *
467481
threadstate_getframe(PyThreadState *self)

0 commit comments

Comments
 (0)