Skip to content

Commit 7cdc2a0

Browse files
authored
pycore_pystate.h no longer redefines PyThreadState_GET() (GH-28921)
Redefining the PyThreadState_GET() macro in pycore_pystate.h is useless since it doesn't affect files not including it. Either use _PyThreadState_GET() directly, or don't use pycore_pystate.h internal C API. For example, the _testcapi extension don't use the internal C API, but use the public PyThreadState_Get() function instead. Replace PyThreadState_Get() with _PyThreadState_GET(). The _PyThreadState_GET() macro is more efficient than PyThreadState_Get() and PyThreadState_GET() function calls which call fail with a fatal Python error. posixmodule.c and _ctypes extension now include <windows.h> before pycore header files (like pycore_call.h). _PyTraceback_Add() now uses _PyErr_Fetch()/_PyErr_Restore() instead of PyErr_Fetch()/PyErr_Restore(). The _decimal and _xxsubinterpreters extensions are now built with the Py_BUILD_CORE_MODULE macro defined to get access to the internal C API.
1 parent 7733307 commit 7cdc2a0

23 files changed

+87
-77
lines changed

Include/internal/pycore_call.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11+
#include "pycore_pystate.h" // _PyThreadState_GET()
12+
1113
PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
1214
PyThreadState *tstate,
1315
PyObject *callable,
@@ -36,7 +38,7 @@ _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) {
3638
// Private static inline function variant of public PyObject_CallNoArgs()
3739
static inline PyObject *
3840
_PyObject_CallNoArgs(PyObject *func) {
39-
PyThreadState *tstate = PyThreadState_Get();
41+
PyThreadState *tstate = _PyThreadState_GET();
4042
return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
4143
}
4244

Include/internal/pycore_ceval.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ extern "C" {
1212
struct pyruntimestate;
1313
struct _ceval_runtime_state;
1414

15-
#include "pycore_interp.h" /* PyInterpreterState.eval_frame */
15+
#include "pycore_interp.h" // PyInterpreterState.eval_frame
16+
#include "pycore_pystate.h" // _PyThreadState_GET()
1617

1718
extern void _Py_FinishPendingCalls(PyThreadState *tstate);
1819
extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *);
@@ -93,7 +94,7 @@ static inline int _Py_EnterRecursiveCall(PyThreadState *tstate,
9394
}
9495

9596
static inline int _Py_EnterRecursiveCall_inline(const char *where) {
96-
PyThreadState *tstate = PyThreadState_GET();
97+
PyThreadState *tstate = _PyThreadState_GET();
9798
return _Py_EnterRecursiveCall(tstate, where);
9899
}
99100

@@ -104,7 +105,7 @@ static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) {
104105
}
105106

106107
static inline void _Py_LeaveRecursiveCall_inline(void) {
107-
PyThreadState *tstate = PyThreadState_GET();
108+
PyThreadState *tstate = _PyThreadState_GET();
108109
_Py_LeaveRecursiveCall(tstate);
109110
}
110111

Include/internal/pycore_pystate.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
8282
8383
The caller must hold the GIL.
8484
85-
See also PyThreadState_Get() and PyThreadState_GET(). */
85+
See also PyThreadState_Get() and _PyThreadState_UncheckedGet(). */
8686
static inline PyThreadState*
8787
_PyThreadState_GET(void)
8888
{
@@ -93,10 +93,6 @@ _PyThreadState_GET(void)
9393
#endif
9494
}
9595

96-
/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */
97-
#undef PyThreadState_GET
98-
#define PyThreadState_GET() _PyThreadState_GET()
99-
10096
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func);
10197

10298
static inline void

Include/pystate.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,10 @@ PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *);
6666
6767
The caller must hold the GIL.
6868
69-
See also PyThreadState_GET() and _PyThreadState_GET(). */
69+
See also _PyThreadState_UncheckedGet() and _PyThreadState_GET(). */
7070
PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
7171

72-
/* Get the current Python thread state.
73-
74-
Macro using PyThreadState_Get() or _PyThreadState_GET() depending if
75-
pycore_pystate.h is included or not (this header redefines the macro).
76-
77-
If PyThreadState_Get() is used, issue a fatal error if the current thread
78-
state is NULL.
79-
80-
See also PyThreadState_Get() and _PyThreadState_GET(). */
72+
// Alias to PyThreadState_Get()
8173
#define PyThreadState_GET() PyThreadState_Get()
8274

8375
PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);

Modules/_asynciomodule.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Python.h"
22
#include "pycore_pyerrors.h" // _PyErr_ClearExcState()
3+
#include "pycore_pystate.h" // _PyThreadState_GET()
34
#include <stddef.h> // offsetof()
45

56

@@ -225,7 +226,7 @@ get_running_loop(PyObject **loop)
225226
{
226227
PyObject *rl;
227228

228-
PyThreadState *ts = PyThreadState_Get();
229+
PyThreadState *ts = _PyThreadState_GET();
229230
uint64_t ts_id = PyThreadState_GetID(ts);
230231
if (ts_id == cached_running_holder_tsid && cached_running_holder != NULL) {
231232
// Fast path, check the cache.
@@ -287,7 +288,7 @@ set_running_loop(PyObject *loop)
287288
{
288289
PyObject *ts_dict = NULL;
289290

290-
PyThreadState *tstate = PyThreadState_Get();
291+
PyThreadState *tstate = _PyThreadState_GET();
291292
if (tstate != NULL) {
292293
ts_dict = _PyThreadState_GetDict(tstate); // borrowed
293294
}

Modules/_ctypes/_ctypes.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,16 @@ bytes(cdata)
102102
#define PY_SSIZE_T_CLEAN
103103

104104
#include "Python.h"
105+
// windows.h must be included before pycore internal headers
106+
#ifdef MS_WIN32
107+
# include <windows.h>
108+
#endif
109+
105110
#include "pycore_call.h" // _PyObject_CallNoArgs()
106111
#include "structmember.h" // PyMemberDef
107112

108113
#include <ffi.h>
109114
#ifdef MS_WIN32
110-
#include <windows.h>
111115
#include <malloc.h>
112116
#ifndef IS_INTRESOURCE
113117
#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)

Modules/_ctypes/callbacks.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#include "Python.h"
2+
// windows.h must be included before pycore internal headers
3+
#ifdef MS_WIN32
4+
# include <windows.h>
5+
#endif
6+
27
#include "pycore_call.h" // _PyObject_CallNoArgs()
38
#include "frameobject.h"
49

510
#include <stdbool.h>
611

712
#include <ffi.h>
8-
#ifdef MS_WIN32
9-
#include <windows.h>
10-
#endif
1113
#include "ctypes.h"
1214

1315
/**************************************************************/

Modules/_ctypes/cfield.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#include "Python.h"
2+
// windows.h must be included before pycore internal headers
3+
#ifdef MS_WIN32
4+
# include <windows.h>
5+
#endif
6+
27
#include "pycore_bitutils.h" // _Py_bswap32()
38
#include "pycore_call.h" // _PyObject_CallNoArgs()
49

510
#include <ffi.h>
6-
#ifdef MS_WIN32
7-
#include <windows.h>
8-
#endif
911
#include "ctypes.h"
1012

1113

Modules/_ctypes/stgdict.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
#include "Python.h"
2+
// windows.h must be included before pycore internal headers
3+
#ifdef MS_WIN32
4+
# include <windows.h>
5+
#endif
6+
27
#include "pycore_call.h" // _PyObject_CallNoArgs()
38
#include <ffi.h>
49
#ifdef MS_WIN32
5-
#include <windows.h>
6-
#include <malloc.h>
10+
# include <malloc.h>
711
#endif
812
#include "ctypes.h"
913

Modules/_decimal/_decimal.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828

2929
#include <Python.h>
30+
#include "pycore_pystate.h" // _PyThreadState_GET()
3031
#include "longintrepr.h"
3132
#include "complexobject.h"
3233
#include "mpdecimal.h"
@@ -1511,18 +1512,20 @@ static PyGetSetDef context_getsets [] =
15111512
static PyObject *
15121513
current_context_from_dict(void)
15131514
{
1514-
PyObject *dict;
1515-
PyObject *tl_context;
1516-
PyThreadState *tstate;
1515+
PyThreadState *tstate = _PyThreadState_GET();
1516+
#ifdef Py_DEBUG
1517+
// The caller must hold the GIL
1518+
_Py_EnsureTstateNotNULL(tstate);
1519+
#endif
15171520

1518-
dict = PyThreadState_GetDict();
1521+
PyObject *dict = _PyThreadState_GetDict(tstate);
15191522
if (dict == NULL) {
15201523
PyErr_SetString(PyExc_RuntimeError,
15211524
"cannot get thread state");
15221525
return NULL;
15231526
}
15241527

1525-
tl_context = PyDict_GetItemWithError(dict, tls_context_key);
1528+
PyObject *tl_context = PyDict_GetItemWithError(dict, tls_context_key);
15261529
if (tl_context != NULL) {
15271530
/* We already have a thread local context. */
15281531
CONTEXT_CHECK(tl_context);
@@ -1548,11 +1551,8 @@ current_context_from_dict(void)
15481551

15491552
/* Cache the context of the current thread, assuming that it
15501553
* will be accessed several times before a thread switch. */
1551-
tstate = PyThreadState_GET();
1552-
if (tstate) {
1553-
cached_context = (PyDecContextObject *)tl_context;
1554-
cached_context->tstate = tstate;
1555-
}
1554+
cached_context = (PyDecContextObject *)tl_context;
1555+
cached_context->tstate = tstate;
15561556

15571557
/* Borrowed reference with refcount==1 */
15581558
return tl_context;
@@ -1562,9 +1562,7 @@ current_context_from_dict(void)
15621562
static PyObject *
15631563
current_context(void)
15641564
{
1565-
PyThreadState *tstate;
1566-
1567-
tstate = PyThreadState_GET();
1565+
PyThreadState *tstate = _PyThreadState_GET();
15681566
if (cached_context && cached_context->tstate == tstate) {
15691567
return (PyObject *)cached_context;
15701568
}

Modules/_lsprof.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Python.h"
22
#include "pycore_call.h" // _PyObject_CallNoArgs()
3+
#include "pycore_pystate.h" // _PyThreadState_GET()
34
#include "rotatingtree.h"
45

56
/************************************************************/
@@ -672,7 +673,7 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds)
672673
return NULL;
673674
}
674675

675-
PyThreadState *tstate = PyThreadState_GET();
676+
PyThreadState *tstate = _PyThreadState_GET();
676677
if (_PyEval_SetProfile(tstate, profiler_callback, (PyObject*)self) < 0) {
677678
return NULL;
678679
}
@@ -706,7 +707,7 @@ Stop collecting profiling information.\n\
706707
static PyObject*
707708
profiler_disable(ProfilerObject *self, PyObject* noarg)
708709
{
709-
PyThreadState *tstate = PyThreadState_GET();
710+
PyThreadState *tstate = _PyThreadState_GET();
710711
if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
711712
return NULL;
712713
}
@@ -743,7 +744,7 @@ static void
743744
profiler_dealloc(ProfilerObject *op)
744745
{
745746
if (op->flags & POF_ENABLED) {
746-
PyThreadState *tstate = PyThreadState_GET();
747+
PyThreadState *tstate = _PyThreadState_GET();
747748
if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
748749
PyErr_WriteUnraisable((PyObject *)op);
749750
}

Modules/_testinternalcapi.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
#include "pycore_hashtable.h" // _Py_hashtable_new()
1919
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
2020
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
21-
#include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost()
21+
#include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost()
22+
#include "pycore_pystate.h" // _PyThreadState_GET()
2223

2324

2425
static PyObject *
@@ -31,7 +32,7 @@ get_configs(PyObject *self, PyObject *Py_UNUSED(args))
3132
static PyObject*
3233
get_recursion_depth(PyObject *self, PyObject *Py_UNUSED(args))
3334
{
34-
PyThreadState *tstate = PyThreadState_Get();
35+
PyThreadState *tstate = _PyThreadState_GET();
3536

3637
/* subtract one to ignore the frame of the get_recursion_depth() call */
3738
return PyLong_FromLong(tstate->recursion_depth - 1);

Modules/_threadmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ static PyObject *
13191319
thread__set_sentinel(PyObject *module, PyObject *Py_UNUSED(ignored))
13201320
{
13211321
PyObject *wr;
1322-
PyThreadState *tstate = PyThreadState_Get();
1322+
PyThreadState *tstate = _PyThreadState_GET();
13231323
lockobject *lock;
13241324

13251325
if (tstate->on_delete_data != NULL) {

Modules/_xxsubinterpretersmodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "Python.h"
66
#include "frameobject.h"
77
#include "pycore_frame.h"
8+
#include "pycore_pystate.h" // _PyThreadState_GET()
89
#include "interpreteridobject.h"
910

1011

@@ -2017,7 +2018,7 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds)
20172018
}
20182019

20192020
// Create and initialize the new interpreter.
2020-
PyThreadState *save_tstate = PyThreadState_Get();
2021+
PyThreadState *save_tstate = _PyThreadState_GET();
20212022
// XXX Possible GILState issues?
20222023
PyThreadState *tstate = _Py_NewInterpreter(isolated);
20232024
PyThreadState_Swap(save_tstate);

Modules/posixmodule.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,36 @@
1010
#define PY_SSIZE_T_CLEAN
1111

1212
#include "Python.h"
13-
#include "pycore_call.h" // _PyObject_CallNoArgs()
14-
#include "pycore_fileutils.h" // _Py_closerange()
15-
#include "pycore_moduleobject.h" // _PyModule_GetState()
13+
// Include <windows.h> before pycore internal headers. FSCTL_GET_REPARSE_POINT
14+
// is not exported by <windows.h> if the WIN32_LEAN_AND_MEAN macro is defined,
15+
// whereas pycore_condvar.h defines the WIN32_LEAN_AND_MEAN macro.
1616
#ifdef MS_WINDOWS
17-
/* include <windows.h> early to avoid conflict with pycore_condvar.h:
18-
19-
#define WIN32_LEAN_AND_MEAN
20-
#include <windows.h>
21-
22-
FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
2317
# include <windows.h>
2418
# include <pathcch.h>
2519
#endif
2620

27-
#if !defined(EX_OK) && defined(EXIT_SUCCESS)
28-
#define EX_OK EXIT_SUCCESS
29-
#endif
30-
3121
#ifdef __VXWORKS__
3222
# include "pycore_bitutils.h" // _Py_popcount32()
3323
#endif
24+
#include "pycore_call.h" // _PyObject_CallNoArgs()
25+
#include "pycore_fileutils.h" // _Py_closerange()
26+
#include "pycore_moduleobject.h" // _PyModule_GetState()
3427
#include "pycore_ceval.h" // _PyEval_ReInitThreads()
3528
#include "pycore_import.h" // _PyImport_ReInitLock()
3629
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
3730
#include "pycore_pystate.h" // _PyInterpreterState_GET()
31+
3832
#include "structmember.h" // PyMemberDef
3933
#ifndef MS_WINDOWS
4034
# include "posixmodule.h"
4135
#else
4236
# include "winreparse.h"
4337
#endif
4438

39+
#if !defined(EX_OK) && defined(EXIT_SUCCESS)
40+
# define EX_OK EXIT_SUCCESS
41+
#endif
42+
4543
/* On android API level 21, 'AT_EACCESS' is not declared although
4644
* HAVE_FACCESSAT is defined. */
4745
#ifdef __ANDROID__

Objects/typeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3332,7 +3332,7 @@ type_vectorcall(PyObject *metatype, PyObject *const *args,
33323332
}
33333333
/* In other (much less common) cases, fall back to
33343334
more flexible calling conventions. */
3335-
PyThreadState *tstate = PyThreadState_GET();
3335+
PyThreadState *tstate = _PyThreadState_GET();
33363336
return _PyObject_MakeTpCall(tstate, metatype, args, nargs, kwnames);
33373337
}
33383338

Python/bltinmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
213213
goto error;
214214
}
215215
PyFrameConstructor *f = PyFunction_AS_FRAME_CONSTRUCTOR(func);
216-
PyThreadState *tstate = PyThreadState_GET();
216+
PyThreadState *tstate = _PyThreadState_GET();
217217
cell = _PyEval_Vector(tstate, f, ns, NULL, 0, NULL);
218218
if (cell != NULL) {
219219
if (bases != orig_bases) {

Python/ceval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **);
10641064
PyObject *
10651065
PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
10661066
{
1067-
PyThreadState *tstate = PyThreadState_GET();
1067+
PyThreadState *tstate = _PyThreadState_GET();
10681068
if (locals == NULL) {
10691069
locals = globals;
10701070
}

0 commit comments

Comments
 (0)