Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 0f62f5b

Browse files
author
Anselm Kruis
committed
Merge branch main into main-slp
The outcome of this merge does not compile.
2 parents 48b1d86 + be3b295 commit 0f62f5b

File tree

8 files changed

+129
-109
lines changed

8 files changed

+129
-109
lines changed

Doc/whatsnew/3.8.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,16 @@ Changes in the Python API
571571
* ``PyGC_Head`` struct is changed completely. All code touched the
572572
struct member should be rewritten. (See :issue:`33597`)
573573

574+
* The ``PyInterpreterState`` struct has been moved into the "internal"
575+
header files (specifically Include/internal/pycore_pystate.h). An
576+
opaque ``PyInterpreterState`` is still available as part of the public
577+
API (and stable ABI). The docs indicate that none of the struct's
578+
fields are public, so we hope no one has been using them. However,
579+
if you do rely on one or more of those private fields and have no
580+
alternative then please open a BPO issue. We'll work on helping
581+
you adjust (possibly including adding accessor functions to the
582+
public API). (See :issue:`35886`.)
583+
574584
* Asyncio tasks can now be named, either by passing the ``name`` keyword
575585
argument to :func:`asyncio.create_task` or
576586
the :meth:`~asyncio.loop.create_task` event loop method, or by

Include/cpython/pystate.h

Lines changed: 5 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ extern "C" {
99
#include "cpython/slp_tstate.h"
1010
#endif
1111

12-
typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
13-
1412
/* Placeholders while working on the new configuration API
1513
*
1614
* See PEP 432 for final anticipated contents
@@ -33,67 +31,9 @@ typedef struct {
3331
(_PyMainInterpreterConfig){.install_signal_handlers = -1}
3432
/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */
3533

36-
typedef struct _is {
37-
38-
struct _is *next;
39-
struct _ts *tstate_head;
40-
41-
int64_t id;
42-
int64_t id_refcount;
43-
PyThread_type_lock id_mutex;
44-
45-
PyObject *modules;
46-
PyObject *modules_by_index;
47-
PyObject *sysdict;
48-
PyObject *builtins;
49-
PyObject *importlib;
50-
51-
/* Used in Python/sysmodule.c. */
52-
int check_interval;
53-
54-
/* Used in Modules/_threadmodule.c. */
55-
long num_threads;
56-
/* Support for runtime thread stack size tuning.
57-
A value of 0 means using the platform's default stack size
58-
or the size specified by the THREAD_STACK_SIZE macro. */
59-
/* Used in Python/thread.c. */
60-
size_t pythread_stacksize;
61-
62-
PyObject *codec_search_path;
63-
PyObject *codec_search_cache;
64-
PyObject *codec_error_registry;
65-
int codecs_initialized;
66-
int fscodec_initialized;
67-
68-
_PyCoreConfig core_config;
69-
_PyMainInterpreterConfig config;
70-
#ifdef HAVE_DLOPEN
71-
int dlopenflags;
72-
#endif
73-
74-
PyObject *builtins_copy;
75-
PyObject *import_func;
76-
/* Initialized to PyEval_EvalFrameDefault(). */
77-
_PyFrameEvalFunction eval_frame;
78-
79-
Py_ssize_t co_extra_user_count;
80-
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
81-
82-
#ifdef HAVE_FORK
83-
PyObject *before_forkers;
84-
PyObject *after_forkers_parent;
85-
PyObject *after_forkers_child;
86-
#endif
87-
/* AtExit module */
88-
void (*pyexitfunc)(PyObject *);
89-
PyObject *pyexitmodule;
34+
PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(PyInterpreterState *);
35+
PyAPI_FUNC(_PyMainInterpreterConfig *) _PyInterpreterState_GetMainConfig(PyInterpreterState *);
9036

91-
uint64_t tstate_next_unique_id;
92-
93-
#ifdef STACKLESS
94-
PyStacklessInterpreterState st;
95-
#endif
96-
} PyInterpreterState;
9737

9838
/* State unique per thread */
9939

@@ -129,7 +69,8 @@ typedef struct _err_stackitem {
12969
} _PyErr_StackItem;
13070

13171

132-
typedef struct _ts {
72+
// The PyThreadState typedef is in Include/pystate.h.
73+
struct _ts {
13374
/* See Python/ceval.c for comments explaining most fields */
13475

13576
struct _ts *prev;
@@ -221,10 +162,7 @@ typedef struct _ts {
221162

222163
/* XXX signal handlers should also be here */
223164

224-
#ifdef STACKLESS
225-
PyStacklessState st;
226-
#endif
227-
} PyThreadState;
165+
};
228166

229167
/* Get the current interpreter state.
230168

Include/internal/pycore_pystate.h

Lines changed: 85 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,74 @@ extern "C" {
2020
#include "pycore_slp_pystate.h"
2121
#endif
2222

23-
/* GIL state */
23+
/* interpreter state */
2424

25-
struct _gilstate_runtime_state {
26-
int check_enabled;
27-
/* Assuming the current thread holds the GIL, this is the
28-
PyThreadState for the current thread. */
29-
_Py_atomic_address tstate_current;
30-
PyThreadFrameGetter getframe;
31-
/* The single PyInterpreterState used by this process'
32-
GILState implementation
33-
*/
34-
/* TODO: Given interp_main, it may be possible to kill this ref */
35-
PyInterpreterState *autoInterpreterState;
36-
Py_tss_t autoTSSkey;
37-
};
25+
typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
26+
27+
// The PyInterpreterState typedef is in Include/pystate.h.
28+
struct _is {
29+
30+
struct _is *next;
31+
struct _ts *tstate_head;
32+
33+
int64_t id;
34+
int64_t id_refcount;
35+
PyThread_type_lock id_mutex;
36+
37+
PyObject *modules;
38+
PyObject *modules_by_index;
39+
PyObject *sysdict;
40+
PyObject *builtins;
41+
PyObject *importlib;
42+
43+
/* Used in Python/sysmodule.c. */
44+
int check_interval;
45+
46+
/* Used in Modules/_threadmodule.c. */
47+
long num_threads;
48+
/* Support for runtime thread stack size tuning.
49+
A value of 0 means using the platform's default stack size
50+
or the size specified by the THREAD_STACK_SIZE macro. */
51+
/* Used in Python/thread.c. */
52+
size_t pythread_stacksize;
53+
54+
PyObject *codec_search_path;
55+
PyObject *codec_search_cache;
56+
PyObject *codec_error_registry;
57+
int codecs_initialized;
58+
int fscodec_initialized;
59+
60+
_PyCoreConfig core_config;
61+
_PyMainInterpreterConfig config;
62+
#ifdef HAVE_DLOPEN
63+
int dlopenflags;
64+
#endif
3865

39-
/* hook for PyEval_GetFrame(), requested for Psyco */
40-
#define _PyThreadState_GetFrame _PyRuntime.gilstate.getframe
66+
PyObject *builtins_copy;
67+
PyObject *import_func;
68+
/* Initialized to PyEval_EvalFrameDefault(). */
69+
_PyFrameEvalFunction eval_frame;
4170

42-
/* Issue #26558: Flag to disable PyGILState_Check().
43-
If set to non-zero, PyGILState_Check() always return 1. */
44-
#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled
71+
Py_ssize_t co_extra_user_count;
72+
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
4573

74+
#ifdef HAVE_FORK
75+
PyObject *before_forkers;
76+
PyObject *after_forkers_parent;
77+
PyObject *after_forkers_child;
78+
#endif
79+
/* AtExit module */
80+
void (*pyexitfunc)(PyObject *);
81+
PyObject *pyexitmodule;
4682

47-
/* interpreter state */
83+
uint64_t tstate_next_unique_id;
84+
};
4885

49-
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(PY_INT64_T);
86+
PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T);
5087

51-
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *);
52-
PyAPI_FUNC(void) _PyInterpreterState_IDIncref(PyInterpreterState *);
53-
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *);
88+
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *);
89+
PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *);
90+
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *);
5491

5592

5693
/* cross-interpreter data */
@@ -122,6 +159,30 @@ struct _xidregitem {
122159
};
123160

124161

162+
/* GIL state */
163+
164+
struct _gilstate_runtime_state {
165+
int check_enabled;
166+
/* Assuming the current thread holds the GIL, this is the
167+
PyThreadState for the current thread. */
168+
_Py_atomic_address tstate_current;
169+
PyThreadFrameGetter getframe;
170+
/* The single PyInterpreterState used by this process'
171+
GILState implementation
172+
*/
173+
/* TODO: Given interp_main, it may be possible to kill this ref */
174+
PyInterpreterState *autoInterpreterState;
175+
Py_tss_t autoTSSkey;
176+
};
177+
178+
/* hook for PyEval_GetFrame(), requested for Psyco */
179+
#define _PyThreadState_GetFrame _PyRuntime.gilstate.getframe
180+
181+
/* Issue #26558: Flag to disable PyGILState_Check().
182+
If set to non-zero, PyGILState_Check() always return 1. */
183+
#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled
184+
185+
125186
/* Full Python runtime state */
126187

127188
typedef struct pyruntimestate {

Include/pystate.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,20 @@ struct _frame;
2020
struct _ts;
2121
struct _is;
2222

23-
#ifdef Py_LIMITED_API
23+
/* struct _ts is defined in cpython/pystate.h */
2424
typedef struct _ts PyThreadState;
25+
/* struct _is is defined in internal/pycore_pystate.h */
2526
typedef struct _is PyInterpreterState;
26-
#else
27-
/* PyThreadState and PyInterpreterState are defined in cpython/pystate.h */
28-
#endif
2927

3028
/* State unique per thread */
3129

32-
PyAPI_FUNC(struct _is *) PyInterpreterState_New(void);
33-
PyAPI_FUNC(void) PyInterpreterState_Clear(struct _is *);
34-
PyAPI_FUNC(void) PyInterpreterState_Delete(struct _is *);
30+
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
31+
PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
32+
PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
3533

3634
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
3735
/* New in 3.7 */
38-
PyAPI_FUNC(int64_t) PyInterpreterState_GetID(struct _is *);
36+
PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *);
3937
#endif
4038
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
4139
/* New in 3.3 */
@@ -44,9 +42,9 @@ PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*);
4442
#endif
4543
PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*);
4644

47-
PyAPI_FUNC(struct _ts *) PyThreadState_New(struct _is *);
48-
PyAPI_FUNC(void) PyThreadState_Clear(struct _ts *);
49-
PyAPI_FUNC(void) PyThreadState_Delete(struct _ts *);
45+
PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
46+
PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);
47+
PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *);
5048
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
5149

5250
/* Get the current thread state.
@@ -57,7 +55,7 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
5755
The caller must hold the GIL.
5856
5957
See also PyThreadState_GET() and _PyThreadState_GET(). */
60-
PyAPI_FUNC(struct _ts *) PyThreadState_Get(void);
58+
PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
6159

6260
/* Get the current Python thread state.
6361
@@ -70,7 +68,7 @@ PyAPI_FUNC(struct _ts *) PyThreadState_Get(void);
7068
See also PyThreadState_Get() and _PyThreadState_GET(). */
7169
#define PyThreadState_GET() PyThreadState_Get()
7270

73-
PyAPI_FUNC(struct _ts *) PyThreadState_Swap(struct _ts *);
71+
PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
7472
PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
7573
PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *);
7674

@@ -118,7 +116,7 @@ PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE);
118116
thread-state, even if no auto-thread-state call has been made
119117
on the main thread.
120118
*/
121-
PyAPI_FUNC(struct _ts *) PyGILState_GetThisThreadState(void);
119+
PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void);
122120

123121

124122
#ifndef Py_LIMITED_API
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The implementation of PyInterpreterState has been moved into the internal
2+
header files (guarded by Py_BUILD_CORE).

Modules/_testcapimodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4685,7 +4685,7 @@ static PyObject *
46854685
get_core_config(PyObject *self, PyObject *Py_UNUSED(args))
46864686
{
46874687
PyInterpreterState *interp = _PyInterpreterState_Get();
4688-
const _PyCoreConfig *config = &interp->core_config;
4688+
const _PyCoreConfig *config = _PyInterpreterState_GetCoreConfig(interp);
46894689
return _PyCoreConfig_AsDict(config);
46904690
}
46914691

@@ -4694,7 +4694,7 @@ static PyObject *
46944694
get_main_config(PyObject *self, PyObject *Py_UNUSED(args))
46954695
{
46964696
PyInterpreterState *interp = _PyInterpreterState_Get();
4697-
const _PyMainInterpreterConfig *config = &interp->config;
4697+
const _PyMainInterpreterConfig *config = _PyInterpreterState_GetMainConfig(interp);
46984698
return _PyMainInterpreterConfig_AsDict(config);
46994699
}
47004700

Programs/_testembed.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ dump_config_impl(void)
315315

316316
/* core config */
317317
PyInterpreterState *interp = _PyInterpreterState_Get();
318-
const _PyCoreConfig *core_config = &interp->core_config;
318+
const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
319319
dict = _PyCoreConfig_AsDict(core_config);
320320
if (dict == NULL) {
321321
goto error;
@@ -326,7 +326,7 @@ dump_config_impl(void)
326326
Py_CLEAR(dict);
327327

328328
/* main config */
329-
const _PyMainInterpreterConfig *main_config = &interp->config;
329+
const _PyMainInterpreterConfig *main_config = _PyInterpreterState_GetMainConfig(interp);
330330
dict = _PyMainInterpreterConfig_AsDict(main_config);
331331
if (dict == NULL) {
332332
goto error;

Python/pystate.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,17 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp)
430430
}
431431
}
432432

433+
_PyCoreConfig *
434+
_PyInterpreterState_GetCoreConfig(PyInterpreterState *interp)
435+
{
436+
return &interp->core_config;
437+
}
438+
439+
_PyMainInterpreterConfig *
440+
_PyInterpreterState_GetMainConfig(PyInterpreterState *interp)
441+
{
442+
return &interp->config;
443+
}
433444

434445
/* Default implementation for _PyThreadState_GetFrame */
435446
static struct _frame *

0 commit comments

Comments
 (0)