]> granicus.if.org Git - python/commitdiff
bpo-36124: Add PyInterpreterState.dict. (gh-12132)
authorEric Snow <ericsnowcurrently@gmail.com>
Fri, 15 Mar 2019 23:47:43 +0000 (17:47 -0600)
committerGitHub <noreply@github.com>
Fri, 15 Mar 2019 23:47:43 +0000 (17:47 -0600)
Doc/c-api/init.rst
Include/internal/pycore_pystate.h
Include/pystate.h
Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst [new file with mode: 0644]
Python/pystate.c

index 6b5290a7ebbb004e23ee17963a13409112e413cc..2c6d21fa9da187b5206146bb15619922edf044bf 100644 (file)
@@ -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
index 945d9923a8841a69d6cffe0965038b45599f6961..703a85b96b4e380e554e1d21ae232cc8e630a0b2 100644 (file)
@@ -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(). */
index a79a2e60e21077066e2db4ed7f774e839e7ff836..4c25e3f7ef84b5d8c3f22ef4b4f5cc5db7d1d357 100644 (file)
@@ -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 (file)
index 0000000..ee9b0c1
--- /dev/null
@@ -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.
index cdf5a698cbabd23d9c7541d4578cf03a26cd3177..6a2dc102ecfebc6cd759855f4e856f58084c2187 100644 (file)
@@ -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)