From 79511398d144139dd0aaf587466f59af43db3efc Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 1 Feb 2019 15:45:29 -0700 Subject: [PATCH 1/8] Add 2 PyInterpreterState getters. --- Include/cpython/pystate.h | 4 ++++ Python/pystate.c | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 78e9a5ed1013d8..b4079e5ed5dedb 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -88,6 +88,10 @@ typedef struct _is { uint64_t tstate_next_unique_id; } PyInterpreterState; +PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(struct _is *); +PyAPI_FUNC(_PyMainInterpreterConfig *) _PyInterpreterState_GetMainConfig(struct _is *); + + /* State unique per thread */ /* Py_tracefunc return -1 when raising an exception, or 0 for success. */ diff --git a/Python/pystate.c b/Python/pystate.c index 4dc3b81e4cdb97..a5aaba07060747 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -404,6 +404,17 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) } } +_PyCoreConfig * +_PyInterpreterState_GetCoreConfig(PyInterpreterState *interp) +{ + return &interp->core_config; +} + +_PyMainInterpreterConfig * +_PyInterpreterState_GetMainConfig(PyInterpreterState *interp) +{ + return &interp->config; +} /* Default implementation for _PyThreadState_GetFrame */ static struct _frame * From f37e6c1d83a474af6dd914637c7e84139a37b9f9 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 1 Feb 2019 15:45:06 -0700 Subject: [PATCH 2/8] Move PyInterpreterState to the internal header file. --- Include/cpython/pystate.h | 78 ++++------------------- Include/import.h | 4 ++ Include/internal/pycore_pystate.h | 100 ++++++++++++++++++++++++------ Include/traceback.h | 3 + Modules/_testcapimodule.c | 4 +- 5 files changed, 101 insertions(+), 88 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index b4079e5ed5dedb..ee934c6982411b 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -6,8 +6,6 @@ extern "C" { #endif -typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); - /* Placeholders while working on the new configuration API * * See PEP 432 for final anticipated contents @@ -30,63 +28,11 @@ typedef struct { (_PyMainInterpreterConfig){.install_signal_handlers = -1} /* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */ -typedef struct _is { - - struct _is *next; - struct _ts *tstate_head; - - int64_t id; - int64_t id_refcount; - PyThread_type_lock id_mutex; - - PyObject *modules; - PyObject *modules_by_index; - PyObject *sysdict; - PyObject *builtins; - PyObject *importlib; - - /* Used in Python/sysmodule.c. */ - int check_interval; - - /* Used in Modules/_threadmodule.c. */ - long num_threads; - /* Support for runtime thread stack size tuning. - A value of 0 means using the platform's default stack size - or the size specified by the THREAD_STACK_SIZE macro. */ - /* Used in Python/thread.c. */ - size_t pythread_stacksize; - - PyObject *codec_search_path; - PyObject *codec_search_cache; - PyObject *codec_error_registry; - int codecs_initialized; - int fscodec_initialized; - - _PyCoreConfig core_config; - _PyMainInterpreterConfig config; -#ifdef HAVE_DLOPEN - int dlopenflags; -#endif - - PyObject *builtins_copy; - PyObject *import_func; - /* Initialized to PyEval_EvalFrameDefault(). */ - _PyFrameEvalFunction eval_frame; - - Py_ssize_t co_extra_user_count; - freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; - -#ifdef HAVE_FORK - PyObject *before_forkers; - PyObject *after_forkers_parent; - PyObject *after_forkers_child; +#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) +typedef struct _is PyInterpreterState; +#else +/* PyInterpreterState is defined in internal/pycore_pystate.h */ #endif - /* AtExit module */ - void (*pyexitfunc)(PyObject *); - PyObject *pyexitmodule; - - uint64_t tstate_next_unique_id; -} PyInterpreterState; PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(struct _is *); PyAPI_FUNC(_PyMainInterpreterConfig *) _PyInterpreterState_GetMainConfig(struct _is *); @@ -131,7 +77,7 @@ typedef struct _ts { struct _ts *prev; struct _ts *next; - PyInterpreterState *interp; + struct _is *interp; struct _frame *frame; int recursion_depth; @@ -226,11 +172,11 @@ typedef struct _ts { interpreter. It cannot return NULL. The caller must hold the GIL.*/ -PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); +PyAPI_FUNC(struct _is *) _PyInterpreterState_Get(void); PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); PyAPI_FUNC(void) _PyState_ClearModules(void); -PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(struct _is *); PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *); PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); PyAPI_FUNC(void) _PyGILState_Reinit(void); @@ -254,7 +200,7 @@ PyAPI_FUNC(int) PyGILState_Check(void); is called and after _PyGILState_Fini() is called. See also _PyInterpreterState_Get() and _PyInterpreterState_GET_UNSAFE(). */ -PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); +PyAPI_FUNC(struct _is *) _PyGILState_GetInterpreterStateUnsafe(void); /* The implementation of sys._current_frames() Returns a dict mapping thread id to that thread's current frame. @@ -263,10 +209,10 @@ PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(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); -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); -PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); +PyAPI_FUNC(struct _is *) PyInterpreterState_Main(void); +PyAPI_FUNC(struct _is *) PyInterpreterState_Head(void); +PyAPI_FUNC(struct _is *) PyInterpreterState_Next(struct _is *); +PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(struct _is *); PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); diff --git a/Include/import.h b/Include/import.h index c664803478a551..30066c170dc1b0 100644 --- a/Include/import.h +++ b/Include/import.h @@ -7,6 +7,10 @@ extern "C" { #endif +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) +#include "internal/pycore_pystate.h" +#endif + #ifndef Py_LIMITED_API PyAPI_FUNC(_PyInitError) _PyImportZip_Init(void); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 4f5545aaa45fab..370efe83cba350 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -17,31 +17,67 @@ extern "C" { #include "pycore_warnings.h" -/* GIL state */ +/* interpreter state */ -struct _gilstate_runtime_state { - int check_enabled; - /* Assuming the current thread holds the GIL, this is the - PyThreadState for the current thread. */ - _Py_atomic_address tstate_current; - PyThreadFrameGetter getframe; - /* The single PyInterpreterState used by this process' - GILState implementation - */ - /* TODO: Given interp_main, it may be possible to kill this ref */ - PyInterpreterState *autoInterpreterState; - Py_tss_t autoTSSkey; -}; +typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); -/* hook for PyEval_GetFrame(), requested for Psyco */ -#define _PyThreadState_GetFrame _PyRuntime.gilstate.getframe +typedef struct _is { -/* Issue #26558: Flag to disable PyGILState_Check(). - If set to non-zero, PyGILState_Check() always return 1. */ -#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled + struct _is *next; + struct _ts *tstate_head; + int64_t id; + int64_t id_refcount; + PyThread_type_lock id_mutex; -/* interpreter state */ + PyObject *modules; + PyObject *modules_by_index; + PyObject *sysdict; + PyObject *builtins; + PyObject *importlib; + + /* Used in Python/sysmodule.c. */ + int check_interval; + + /* Used in Modules/_threadmodule.c. */ + long num_threads; + /* Support for runtime thread stack size tuning. + A value of 0 means using the platform's default stack size + or the size specified by the THREAD_STACK_SIZE macro. */ + /* Used in Python/thread.c. */ + size_t pythread_stacksize; + + PyObject *codec_search_path; + PyObject *codec_search_cache; + PyObject *codec_error_registry; + int codecs_initialized; + int fscodec_initialized; + + _PyCoreConfig core_config; + _PyMainInterpreterConfig config; +#ifdef HAVE_DLOPEN + int dlopenflags; +#endif + + PyObject *builtins_copy; + PyObject *import_func; + /* Initialized to PyEval_EvalFrameDefault(). */ + _PyFrameEvalFunction eval_frame; + + Py_ssize_t co_extra_user_count; + freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; + +#ifdef HAVE_FORK + PyObject *before_forkers; + PyObject *after_forkers_parent; + PyObject *after_forkers_child; +#endif + /* AtExit module */ + void (*pyexitfunc)(PyObject *); + PyObject *pyexitmodule; + + uint64_t tstate_next_unique_id; +} PyInterpreterState; PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(PY_INT64_T); @@ -119,6 +155,30 @@ struct _xidregitem { }; +/* GIL state */ + +struct _gilstate_runtime_state { + int check_enabled; + /* Assuming the current thread holds the GIL, this is the + PyThreadState for the current thread. */ + _Py_atomic_address tstate_current; + PyThreadFrameGetter getframe; + /* The single PyInterpreterState used by this process' + GILState implementation + */ + /* TODO: Given interp_main, it may be possible to kill this ref */ + PyInterpreterState *autoInterpreterState; + Py_tss_t autoTSSkey; +}; + +/* hook for PyEval_GetFrame(), requested for Psyco */ +#define _PyThreadState_GetFrame _PyRuntime.gilstate.getframe + +/* Issue #26558: Flag to disable PyGILState_Check(). + If set to non-zero, PyGILState_Check() always return 1. */ +#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled + + /* Full Python runtime state */ typedef struct pyruntimestate { diff --git a/Include/traceback.h b/Include/traceback.h index b5874100f477a5..161645ca58e3f5 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -5,6 +5,9 @@ extern "C" { #endif +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) +#include "internal/pycore_pystate.h" +#endif #include "pystate.h" struct _frame; diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 85810f30b1c528..350ef771630eab 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4685,7 +4685,7 @@ static PyObject * get_core_config(PyObject *self, PyObject *Py_UNUSED(args)) { PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyCoreConfig *config = &interp->core_config; + const _PyCoreConfig *config = _PyInterpreterState_GetCoreConfig(interp); return _PyCoreConfig_AsDict(config); } @@ -4694,7 +4694,7 @@ static PyObject * get_main_config(PyObject *self, PyObject *Py_UNUSED(args)) { PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyMainInterpreterConfig *config = &interp->config; + const _PyMainInterpreterConfig *config = _PyInterpreterState_GetMainConfig(interp); return _PyMainInterpreterConfig_AsDict(config); } From 51b1941dab2f9ead1596e58087cc9adcdf79326e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 1 Feb 2019 18:24:30 -0700 Subject: [PATCH 3/8] Add a NEWS entry. --- Doc/whatsnew/3.8.rst | 10 ++++++++++ .../2019-02-01-18-12-14.bpo-35886.0Z-C0V.rst | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-01-18-12-14.bpo-35886.0Z-C0V.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 370ef4604834f4..60c31e3c8afe1f 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -475,6 +475,16 @@ Changes in the Python API * ``PyGC_Head`` struct is changed completely. All code touched the struct member should be rewritten. (See :issue:`33597`) +* The ``PyInterpreterState`` struct has been moved into the "internal" + header files (specifically Include/internal/pycore_pystate.h). An + opaque ``PyInterpreterState`` is still available as part of the public + API (and stable ABI). The docs indicate that none of the struct's + fields are public, so we hope no one has been using them. However, + if you do rely on one or more of those private fields and have no + alternative then please open a BPO issue. We'll work on helping + you adjust (possibly including adding accessor functions to the + public API). (See :issue:`35886`.) + * Asyncio tasks can now be named, either by passing the ``name`` keyword argument to :func:`asyncio.create_task` or the :meth:`~asyncio.loop.create_task` event loop method, or by diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-01-18-12-14.bpo-35886.0Z-C0V.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-01-18-12-14.bpo-35886.0Z-C0V.rst new file mode 100644 index 00000000000000..362a7a61d46ffc --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-01-18-12-14.bpo-35886.0Z-C0V.rst @@ -0,0 +1,2 @@ +The implementation of PyInterpreterState has been moved into the internal +header files (guarded by Py_BUILD_CORE). From 5801b60a2ef93a5c653866f58c7faf03160b9b96 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 8 Feb 2019 13:30:02 -0700 Subject: [PATCH 4/8] Fix the includes. --- Include/import.h | 2 +- Include/traceback.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/import.h b/Include/import.h index 30066c170dc1b0..8ea3f623261652 100644 --- a/Include/import.h +++ b/Include/import.h @@ -8,7 +8,7 @@ extern "C" { #endif #if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) -#include "internal/pycore_pystate.h" +#include "pycore_pystate.h" #endif #ifndef Py_LIMITED_API diff --git a/Include/traceback.h b/Include/traceback.h index 161645ca58e3f5..4d0b96cfaf3b59 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -6,7 +6,7 @@ extern "C" { #endif #if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) -#include "internal/pycore_pystate.h" +#include "pycore_pystate.h" #endif #include "pystate.h" From 76bac2119c43405605bc22aaab357aca639f20bf Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 8 Feb 2019 17:26:35 -0700 Subject: [PATCH 5/8] Always typedef PyInterpreterState in Include/pystate.h. --- Include/cpython/pystate.h | 25 +++++++++++-------------- Include/import.h | 4 ---- Include/internal/pycore_pystate.h | 13 +++++++------ Include/pystate.h | 15 ++++++++------- Include/traceback.h | 3 --- 5 files changed, 26 insertions(+), 34 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index ee934c6982411b..283af0e8ade1fc 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -28,14 +28,11 @@ typedef struct { (_PyMainInterpreterConfig){.install_signal_handlers = -1} /* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */ -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -typedef struct _is PyInterpreterState; -#else /* PyInterpreterState is defined in internal/pycore_pystate.h */ -#endif +//typedef struct _is PyInterpreterState; -PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(struct _is *); -PyAPI_FUNC(_PyMainInterpreterConfig *) _PyInterpreterState_GetMainConfig(struct _is *); +PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(PyInterpreterState *); +PyAPI_FUNC(_PyMainInterpreterConfig *) _PyInterpreterState_GetMainConfig(PyInterpreterState *); /* State unique per thread */ @@ -77,7 +74,7 @@ typedef struct _ts { struct _ts *prev; struct _ts *next; - struct _is *interp; + PyInterpreterState *interp; struct _frame *frame; int recursion_depth; @@ -172,11 +169,11 @@ typedef struct _ts { interpreter. It cannot return NULL. The caller must hold the GIL.*/ -PyAPI_FUNC(struct _is *) _PyInterpreterState_Get(void); +PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); PyAPI_FUNC(void) _PyState_ClearModules(void); -PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(struct _is *); +PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *); PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); PyAPI_FUNC(void) _PyGILState_Reinit(void); @@ -200,7 +197,7 @@ PyAPI_FUNC(int) PyGILState_Check(void); is called and after _PyGILState_Fini() is called. See also _PyInterpreterState_Get() and _PyInterpreterState_GET_UNSAFE(). */ -PyAPI_FUNC(struct _is *) _PyGILState_GetInterpreterStateUnsafe(void); +PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); /* The implementation of sys._current_frames() Returns a dict mapping thread id to that thread's current frame. @@ -209,10 +206,10 @@ PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); /* Routines for advanced debuggers, requested by David Beazley. Don't use unless you know what you are doing! */ -PyAPI_FUNC(struct _is *) PyInterpreterState_Main(void); -PyAPI_FUNC(struct _is *) PyInterpreterState_Head(void); -PyAPI_FUNC(struct _is *) PyInterpreterState_Next(struct _is *); -PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(struct _is *); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); diff --git a/Include/import.h b/Include/import.h index 8ea3f623261652..c664803478a551 100644 --- a/Include/import.h +++ b/Include/import.h @@ -7,10 +7,6 @@ extern "C" { #endif -#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) -#include "pycore_pystate.h" -#endif - #ifndef Py_LIMITED_API PyAPI_FUNC(_PyInitError) _PyImportZip_Init(void); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 370efe83cba350..7796223b59e650 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -21,7 +21,8 @@ extern "C" { typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); -typedef struct _is { +// The PyInterpreterState typedef is in Include/pystate.h. +struct _is { struct _is *next; struct _ts *tstate_head; @@ -77,13 +78,13 @@ typedef struct _is { PyObject *pyexitmodule; uint64_t tstate_next_unique_id; -} PyInterpreterState; +}; -PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(PY_INT64_T); +PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T); -PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); -PyAPI_FUNC(void) _PyInterpreterState_IDIncref(PyInterpreterState *); -PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); +PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *); +PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *); +PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *); /* cross-interpreter data */ diff --git a/Include/pystate.h b/Include/pystate.h index ba5e9883306a70..02a0643d74c2e7 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -20,22 +20,23 @@ struct _frame; struct _ts; struct _is; +/* struct _is is defined in internal/pycore_pystate.h */ +typedef struct _is PyInterpreterState; #ifdef Py_LIMITED_API typedef struct _ts PyThreadState; -typedef struct _is PyInterpreterState; #else -/* PyThreadState and PyInterpreterState are defined in cpython/pystate.h */ +/* PyThreadState is defined in cpython/pystate.h */ #endif /* State unique per thread */ -PyAPI_FUNC(struct _is *) PyInterpreterState_New(void); -PyAPI_FUNC(void) PyInterpreterState_Clear(struct _is *); -PyAPI_FUNC(void) PyInterpreterState_Delete(struct _is *); +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 >= 0x03070000 /* New in 3.7 */ -PyAPI_FUNC(int64_t) PyInterpreterState_GetID(struct _is *); +PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* New in 3.3 */ @@ -44,7 +45,7 @@ PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*); #endif PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*); -PyAPI_FUNC(struct _ts *) PyThreadState_New(struct _is *); +PyAPI_FUNC(struct _ts *) PyThreadState_New(PyInterpreterState *); PyAPI_FUNC(void) PyThreadState_Clear(struct _ts *); PyAPI_FUNC(void) PyThreadState_Delete(struct _ts *); PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); diff --git a/Include/traceback.h b/Include/traceback.h index 4d0b96cfaf3b59..b5874100f477a5 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -5,9 +5,6 @@ extern "C" { #endif -#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) -#include "pycore_pystate.h" -#endif #include "pystate.h" struct _frame; From f2d776c44f0636a3c43c10e53d635cd37d1ed8c1 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 8 Feb 2019 17:34:36 -0700 Subject: [PATCH 6/8] Always typedef PyThreadState in Include/pystate.h. --- Include/cpython/pystate.h | 5 +++-- Include/pystate.h | 20 ++++++++------------ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 283af0e8ade1fc..d8dc4a121a9874 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -69,7 +69,8 @@ typedef struct _err_stackitem { } _PyErr_StackItem; -typedef struct _ts { +// The PyThreadState typedef is in Include/pystate.h. +struct _ts { /* See Python/ceval.c for comments explaining most fields */ struct _ts *prev; @@ -161,7 +162,7 @@ typedef struct _ts { /* XXX signal handlers should also be here */ -} PyThreadState; +}; /* Get the current interpreter state. diff --git a/Include/pystate.h b/Include/pystate.h index 02a0643d74c2e7..4e1613b60c7982 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -20,13 +20,9 @@ struct _frame; struct _ts; struct _is; -/* struct _is is defined in internal/pycore_pystate.h */ -typedef struct _is PyInterpreterState; -#ifdef Py_LIMITED_API +/* struct _is and struct _ts are defined in internal/pycore_pystate.h */ typedef struct _ts PyThreadState; -#else -/* PyThreadState is defined in cpython/pystate.h */ -#endif +typedef struct _is PyInterpreterState; /* State unique per thread */ @@ -45,9 +41,9 @@ PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*); #endif PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*); -PyAPI_FUNC(struct _ts *) PyThreadState_New(PyInterpreterState *); -PyAPI_FUNC(void) PyThreadState_Clear(struct _ts *); -PyAPI_FUNC(void) PyThreadState_Delete(struct _ts *); +PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); +PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); /* Get the current thread state. @@ -58,7 +54,7 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); The caller must hold the GIL. See also PyThreadState_GET() and _PyThreadState_GET(). */ -PyAPI_FUNC(struct _ts *) PyThreadState_Get(void); +PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); /* Get the current Python thread state. @@ -71,7 +67,7 @@ PyAPI_FUNC(struct _ts *) PyThreadState_Get(void); See also PyThreadState_Get() and _PyThreadState_GET(). */ #define PyThreadState_GET() PyThreadState_Get() -PyAPI_FUNC(struct _ts *) PyThreadState_Swap(struct _ts *); +PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *); @@ -119,7 +115,7 @@ PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE); thread-state, even if no auto-thread-state call has been made on the main thread. */ -PyAPI_FUNC(struct _ts *) PyGILState_GetThisThreadState(void); +PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); #ifndef Py_LIMITED_API From 64658fc34ebf5eee1e7ff3a2ea8d15cb062db0dc Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 8 Feb 2019 17:57:43 -0700 Subject: [PATCH 7/8] Fix _testembed.c. --- Programs/_testembed.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 22212bff52d4a1..e28d94c175e6a5 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -315,7 +315,7 @@ dump_config_impl(void) /* core config */ PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyCoreConfig *core_config = &interp->core_config; + const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp); dict = _PyCoreConfig_AsDict(core_config); if (dict == NULL) { goto error; @@ -326,7 +326,7 @@ dump_config_impl(void) Py_CLEAR(dict); /* main config */ - const _PyMainInterpreterConfig *main_config = &interp->config; + const _PyMainInterpreterConfig *main_config = _PyInterpreterState_GetMainConfig(interp); dict = _PyMainInterpreterConfig_AsDict(main_config); if (dict == NULL) { goto error; From c19dd546ae299ea9f6ac1f0207b93885f9d527ce Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 18 Feb 2019 13:47:12 -0700 Subject: [PATCH 8/8] Fix some comments. --- Include/cpython/pystate.h | 3 --- Include/pystate.h | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index d8dc4a121a9874..0da59d96d1f75e 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -28,9 +28,6 @@ typedef struct { (_PyMainInterpreterConfig){.install_signal_handlers = -1} /* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */ -/* PyInterpreterState is defined in internal/pycore_pystate.h */ -//typedef struct _is PyInterpreterState; - PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(PyInterpreterState *); PyAPI_FUNC(_PyMainInterpreterConfig *) _PyInterpreterState_GetMainConfig(PyInterpreterState *); diff --git a/Include/pystate.h b/Include/pystate.h index 4e1613b60c7982..a541dc8f00969d 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -20,8 +20,9 @@ struct _frame; struct _ts; struct _is; -/* struct _is and struct _ts are defined in internal/pycore_pystate.h */ +/* struct _ts is defined in cpython/pystate.h */ typedef struct _ts PyThreadState; +/* struct _is is defined in internal/pycore_pystate.h */ typedef struct _is PyInterpreterState; /* State unique per thread */