From b403d1a4502d8794b1182af4041742b8a6aa92af Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 2 Jul 2023 01:44:07 +0200 Subject: [PATCH 1/2] gh-106320: Remove private _PyInterpreterState functions Remove private _PyThreadState and _PyInterpreterState C API functions: move them to the internal C API (pycore_pystate.h and pycore_interp.h). Don't export most of these functions anymore, but still export functions used by tests. Remove _PyThreadState_Prealloc() and _PyThreadState_Init() from the C API, but keep it in the stable API. --- Include/cpython/pystate.h | 57 ------------------------------ Include/internal/pycore_interp.h | 37 +++++++++++++++++++ Include/internal/pycore_pystate.h | 19 ++++++++-- Modules/_testcapimodule.c | 5 --- Modules/_testinternalcapi.c | 22 ++++++++++++ Modules/_xxsubinterpretersmodule.c | 6 +++- Python/compile.c | 1 + Python/frozenmain.c | 3 +- Python/pystate.c | 6 ++-- 9 files changed, 86 insertions(+), 70 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 7d9e41bc2dd7ab..e08bcdaf197628 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -40,8 +40,6 @@ PyAPI_FUNC(int) _PyInterpreterState_HasFeature(PyInterpreterState *interp, PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); -PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); - /* State unique per thread */ @@ -261,16 +259,10 @@ struct _ts { /* other API */ -/* An alias for the internal _PyThreadState_New(), - kept for stable ABI compatibility. */ -PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); - /* Similar to PyThreadState_Get(), but don't issue a fatal error * if it is NULL. */ PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); -PyAPI_FUNC(PyObject *) _PyThreadState_GetDict(PyThreadState *tstate); - // Disable tracing and profiling. PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); @@ -295,16 +287,6 @@ PyAPI_FUNC(int) PyGILState_Check(void); See also PyInterpreterState_Get() and _PyInterpreterState_GET(). */ PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); -/* The implementation of sys._current_frames() Returns a dict mapping - thread id to that thread's current frame. -*/ -PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); - -/* The implementation of sys._current_exceptions() Returns a dict mapping - thread id to that thread's current exception. -*/ -PyAPI_FUNC(PyObject *) _PyThread_CurrentExceptions(void); - /* Routines for advanced debuggers, requested by David Beazley. Don't use unless you know what you are doing! */ PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); @@ -324,45 +306,6 @@ PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc( PyInterpreterState *interp, _PyFrameEvalFunction eval_frame); -PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *interp); - -/* Get a copy of the current interpreter configuration. - - Return 0 on success. Raise an exception and return -1 on error. - - The caller must initialize 'config', using PyConfig_InitPythonConfig() - for example. - - Python must be preinitialized to call this method. - The caller must hold the GIL. - - Once done with the configuration, PyConfig_Clear() must be called to clear - it. */ -PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( - struct PyConfig *config); - -/* Set the configuration of the current interpreter. - - This function should be called during or just after the Python - initialization. - - Update the sys module with the new configuration. If the sys module was - modified directly after the Python initialization, these changes are lost. - - Some configuration like faulthandler or warnoptions can be updated in the - configuration, but don't reconfigure Python (don't enable/disable - faulthandler and don't reconfigure warnings filters). - - Return 0 on success. Raise an exception and return -1 on error. - - The configuration should come from _PyInterpreterState_GetConfigCopy(). */ -PyAPI_FUNC(int) _PyInterpreterState_SetConfig( - const struct PyConfig *config); - -// Get the configuration of the current interpreter. -// The caller must hold the GIL. -PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); - /* cross-interpreter data */ diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 466ae6fbbdc4eb..a1f00df12d6ac9 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -238,6 +238,43 @@ PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); +PyAPI_FUNC(PyObject*) _PyInterpreterState_GetMainModule(PyInterpreterState *); + +extern const PyConfig* _PyInterpreterState_GetConfig(PyInterpreterState *interp); + +/* Get a copy of the current interpreter configuration. + + Return 0 on success. Raise an exception and return -1 on error. + + The caller must initialize 'config', using PyConfig_InitPythonConfig() + for example. + + Python must be preinitialized to call this method. + The caller must hold the GIL. + + Once done with the configuration, PyConfig_Clear() must be called to clear + it. */ +PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( + struct PyConfig *config); + +/* Set the configuration of the current interpreter. + + This function should be called during or just after the Python + initialization. + + Update the sys module with the new configuration. If the sys module was + modified directly after the Python initialization, these changes are lost. + + Some configuration like faulthandler or warnoptions can be updated in the + configuration, but don't reconfigure Python (don't enable/disable + faulthandler and don't reconfigure warnings filters). + + Return 0 on success. Raise an exception and return -1 on error. + + The configuration should come from _PyInterpreterState_GetConfigCopy(). */ +PyAPI_FUNC(int) _PyInterpreterState_SetConfig( + const struct PyConfig *config); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 63fc6b2129ce2a..0bd11631dda736 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -123,9 +123,6 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) { PyAPI_FUNC(PyThreadState *) _PyThreadState_New(PyInterpreterState *interp); PyAPI_FUNC(void) _PyThreadState_Bind(PyThreadState *tstate); -// We keep this around exclusively for stable ABI compatibility. -PyAPI_FUNC(void) _PyThreadState_Init( - PyThreadState *tstate); PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); extern void _PyThreadState_InitDetached(PyThreadState *, PyInterpreterState *); @@ -133,6 +130,18 @@ extern void _PyThreadState_ClearDetached(PyThreadState *); extern void _PyThreadState_BindDetached(PyThreadState *); extern void _PyThreadState_UnbindDetached(PyThreadState *); +PyAPI_FUNC(PyObject*) _PyThreadState_GetDict(PyThreadState *tstate); + +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +extern PyObject* _PyThread_CurrentFrames(void); + +/* The implementation of sys._current_exceptions() Returns a dict mapping + thread id to that thread's current exception. +*/ +extern PyObject* _PyThread_CurrentExceptions(void); + /* Other */ @@ -161,6 +170,10 @@ PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); #define HEAD_UNLOCK(runtime) \ PyThread_release_lock((runtime)->interpreters.mutex) +// Get the configuration of the current interpreter. +// The caller must hold the GIL. +extern const PyConfig* _Py_GetConfig(void); + #ifdef __cplusplus } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index ec2e64f2f46fc1..398450d804f5c5 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2714,11 +2714,6 @@ test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) assert(PyDict_Check(dict)); // dict is a borrowed reference - // private _PyThreadState_GetDict() - PyObject *dict2 = _PyThreadState_GetDict(tstate); - assert(dict2 == dict); - // dict2 is a borrowed reference - // PyThreadState_GetInterpreter() PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate); assert(interp != NULL); diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index f6ae389ea05679..2e0609dcae5b7d 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1234,6 +1234,27 @@ tracemalloc_get_traceback(PyObject *self, PyObject *args) } +// Test PyThreadState C API +static PyObject * +test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) +{ + // PyThreadState_Get() + PyThreadState *tstate = PyThreadState_Get(); + assert(tstate != NULL); + + // test _PyThreadState_GetDict() + PyObject *dict = PyThreadState_GetDict(); + assert(dict != NULL); + // dict is a borrowed reference + + PyObject *dict2 = _PyThreadState_GetDict(tstate); + assert(dict2 == dict); + // dict2 is a borrowed reference + + Py_RETURN_NONE; +} + + static PyMethodDef module_functions[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, @@ -1284,6 +1305,7 @@ static PyMethodDef module_functions[] = { {"_PyTime_ObjectToTimespec", test_pytime_object_to_timespec, METH_VARARGS}, {"_PyTime_ObjectToTimeval", test_pytime_object_to_timeval, METH_VARARGS}, {"_PyTraceMalloc_GetTraceback", tracemalloc_get_traceback, METH_VARARGS}, + {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 4801f37d6f6c5f..40dea170fd1f8b 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1,8 +1,12 @@ - /* interpreters module */ /* low-level access to interpreter primitives */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" +#include "pycore_interp.h" // _PyInterpreterState_GetMainModule() #include "interpreteridobject.h" diff --git a/Python/compile.c b/Python/compile.c index d83bf0855ec257..29ea2742fad0cf 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -33,6 +33,7 @@ #include "pycore_compile.h" #include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_pystate.h" // _Py_GetConfig() #include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST() #include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed diff --git a/Python/frozenmain.c b/Python/frozenmain.c index f8be165f7671df..767f9804903a9e 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -1,7 +1,8 @@ /* Python interpreter main program for frozen scripts */ #include "Python.h" -#include "pycore_runtime.h" // _PyRuntime_Initialize() +#include "pycore_pystate.h" // _Py_GetConfig() +#include "pycore_runtime.h" // _PyRuntime_Initialize() #include #ifdef MS_WINDOWS diff --git a/Python/pystate.c b/Python/pystate.c index 20b02ef22109e7..50ce1d06602106 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1166,7 +1166,7 @@ PyInterpreterState_GetDict(PyInterpreterState *interp) The GIL must be held. */ -PyInterpreterState * +PyInterpreterState* PyInterpreterState_Get(void) { PyThreadState *tstate = current_fast_get(&_PyRuntime); @@ -1408,7 +1408,7 @@ _PyThreadState_New(PyInterpreterState *interp) } // We keep this for stable ABI compabibility. -PyThreadState * +PyAPI_FUNC(PyThreadState*) _PyThreadState_Prealloc(PyInterpreterState *interp) { return _PyThreadState_New(interp); @@ -1416,7 +1416,7 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) // We keep this around for (accidental) stable ABI compatibility. // Realistically, no extensions are using it. -void +PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *tstate) { Py_FatalError("_PyThreadState_Init() is for internal use only"); From fb9243c05d30b9860c8a7be91baad2aadb6db0c0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 2 Jul 2023 03:11:57 +0200 Subject: [PATCH 2/2] Export _Py_GetConfig() --- Include/internal/pycore_pystate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 0bd11631dda736..0659084194d293 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -172,7 +172,7 @@ PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); // Get the configuration of the current interpreter. // The caller must hold the GIL. -extern const PyConfig* _Py_GetConfig(void); +PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); #ifdef __cplusplus pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy