Skip to content

Commit

Permalink
bpo-36124: Add PyInterpreterState.dict. (gh-12132)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericsnowcurrently authored Mar 15, 2019
1 parent c11183c commit d2fdd1f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 2 deletions.
12 changes: 12 additions & 0 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(). */
Expand Down
10 changes: 8 additions & 2 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
14 changes: 14 additions & 0 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit d2fdd1f

Please sign in to comment.