Skip to content

Commit 8571b27

Browse files
authored
gh-106320: Remove private _PyInterpreterState functions (#106325)
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.
1 parent feb51f3 commit 8571b27

File tree

9 files changed

+86
-70
lines changed

9 files changed

+86
-70
lines changed

Include/cpython/pystate.h

-57
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ PyAPI_FUNC(int) _PyInterpreterState_HasFeature(PyInterpreterState *interp,
4040
PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
4141
PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int);
4242

43-
PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *);
44-
4543

4644
/* State unique per thread */
4745

@@ -261,16 +259,10 @@ struct _ts {
261259

262260
/* other API */
263261

264-
/* An alias for the internal _PyThreadState_New(),
265-
kept for stable ABI compatibility. */
266-
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
267-
268262
/* Similar to PyThreadState_Get(), but don't issue a fatal error
269263
* if it is NULL. */
270264
PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
271265

272-
PyAPI_FUNC(PyObject *) _PyThreadState_GetDict(PyThreadState *tstate);
273-
274266
// Disable tracing and profiling.
275267
PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate);
276268

@@ -295,16 +287,6 @@ PyAPI_FUNC(int) PyGILState_Check(void);
295287
See also PyInterpreterState_Get() and _PyInterpreterState_GET(). */
296288
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
297289

298-
/* The implementation of sys._current_frames() Returns a dict mapping
299-
thread id to that thread's current frame.
300-
*/
301-
PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
302-
303-
/* The implementation of sys._current_exceptions() Returns a dict mapping
304-
thread id to that thread's current exception.
305-
*/
306-
PyAPI_FUNC(PyObject *) _PyThread_CurrentExceptions(void);
307-
308290
/* Routines for advanced debuggers, requested by David Beazley.
309291
Don't use unless you know what you are doing! */
310292
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);
@@ -324,45 +306,6 @@ PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
324306
PyInterpreterState *interp,
325307
_PyFrameEvalFunction eval_frame);
326308

327-
PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *interp);
328-
329-
/* Get a copy of the current interpreter configuration.
330-
331-
Return 0 on success. Raise an exception and return -1 on error.
332-
333-
The caller must initialize 'config', using PyConfig_InitPythonConfig()
334-
for example.
335-
336-
Python must be preinitialized to call this method.
337-
The caller must hold the GIL.
338-
339-
Once done with the configuration, PyConfig_Clear() must be called to clear
340-
it. */
341-
PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy(
342-
struct PyConfig *config);
343-
344-
/* Set the configuration of the current interpreter.
345-
346-
This function should be called during or just after the Python
347-
initialization.
348-
349-
Update the sys module with the new configuration. If the sys module was
350-
modified directly after the Python initialization, these changes are lost.
351-
352-
Some configuration like faulthandler or warnoptions can be updated in the
353-
configuration, but don't reconfigure Python (don't enable/disable
354-
faulthandler and don't reconfigure warnings filters).
355-
356-
Return 0 on success. Raise an exception and return -1 on error.
357-
358-
The configuration should come from _PyInterpreterState_GetConfigCopy(). */
359-
PyAPI_FUNC(int) _PyInterpreterState_SetConfig(
360-
const struct PyConfig *config);
361-
362-
// Get the configuration of the current interpreter.
363-
// The caller must hold the GIL.
364-
PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void);
365-
366309

367310
/* cross-interpreter data */
368311

Include/internal/pycore_interp.h

+37
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,43 @@ PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *);
238238
PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *);
239239
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *);
240240

241+
PyAPI_FUNC(PyObject*) _PyInterpreterState_GetMainModule(PyInterpreterState *);
242+
243+
extern const PyConfig* _PyInterpreterState_GetConfig(PyInterpreterState *interp);
244+
245+
/* Get a copy of the current interpreter configuration.
246+
247+
Return 0 on success. Raise an exception and return -1 on error.
248+
249+
The caller must initialize 'config', using PyConfig_InitPythonConfig()
250+
for example.
251+
252+
Python must be preinitialized to call this method.
253+
The caller must hold the GIL.
254+
255+
Once done with the configuration, PyConfig_Clear() must be called to clear
256+
it. */
257+
PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy(
258+
struct PyConfig *config);
259+
260+
/* Set the configuration of the current interpreter.
261+
262+
This function should be called during or just after the Python
263+
initialization.
264+
265+
Update the sys module with the new configuration. If the sys module was
266+
modified directly after the Python initialization, these changes are lost.
267+
268+
Some configuration like faulthandler or warnoptions can be updated in the
269+
configuration, but don't reconfigure Python (don't enable/disable
270+
faulthandler and don't reconfigure warnings filters).
271+
272+
Return 0 on success. Raise an exception and return -1 on error.
273+
274+
The configuration should come from _PyInterpreterState_GetConfigCopy(). */
275+
PyAPI_FUNC(int) _PyInterpreterState_SetConfig(
276+
const struct PyConfig *config);
277+
241278
#ifdef __cplusplus
242279
}
243280
#endif

Include/internal/pycore_pystate.h

+16-3
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,25 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) {
123123

124124
PyAPI_FUNC(PyThreadState *) _PyThreadState_New(PyInterpreterState *interp);
125125
PyAPI_FUNC(void) _PyThreadState_Bind(PyThreadState *tstate);
126-
// We keep this around exclusively for stable ABI compatibility.
127-
PyAPI_FUNC(void) _PyThreadState_Init(
128-
PyThreadState *tstate);
129126
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
130127

131128
extern void _PyThreadState_InitDetached(PyThreadState *, PyInterpreterState *);
132129
extern void _PyThreadState_ClearDetached(PyThreadState *);
133130
extern void _PyThreadState_BindDetached(PyThreadState *);
134131
extern void _PyThreadState_UnbindDetached(PyThreadState *);
135132

133+
PyAPI_FUNC(PyObject*) _PyThreadState_GetDict(PyThreadState *tstate);
134+
135+
/* The implementation of sys._current_frames() Returns a dict mapping
136+
thread id to that thread's current frame.
137+
*/
138+
extern PyObject* _PyThread_CurrentFrames(void);
139+
140+
/* The implementation of sys._current_exceptions() Returns a dict mapping
141+
thread id to that thread's current exception.
142+
*/
143+
extern PyObject* _PyThread_CurrentExceptions(void);
144+
136145

137146
/* Other */
138147

@@ -161,6 +170,10 @@ PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate);
161170
#define HEAD_UNLOCK(runtime) \
162171
PyThread_release_lock((runtime)->interpreters.mutex)
163172

173+
// Get the configuration of the current interpreter.
174+
// The caller must hold the GIL.
175+
PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void);
176+
164177

165178
#ifdef __cplusplus
166179
}

Modules/_testcapimodule.c

-5
Original file line numberDiff line numberDiff line change
@@ -2714,11 +2714,6 @@ test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args))
27142714
assert(PyDict_Check(dict));
27152715
// dict is a borrowed reference
27162716

2717-
// private _PyThreadState_GetDict()
2718-
PyObject *dict2 = _PyThreadState_GetDict(tstate);
2719-
assert(dict2 == dict);
2720-
// dict2 is a borrowed reference
2721-
27222717
// PyThreadState_GetInterpreter()
27232718
PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate);
27242719
assert(interp != NULL);

Modules/_testinternalcapi.c

+22
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,27 @@ tracemalloc_get_traceback(PyObject *self, PyObject *args)
12341234
}
12351235

12361236

1237+
// Test PyThreadState C API
1238+
static PyObject *
1239+
test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args))
1240+
{
1241+
// PyThreadState_Get()
1242+
PyThreadState *tstate = PyThreadState_Get();
1243+
assert(tstate != NULL);
1244+
1245+
// test _PyThreadState_GetDict()
1246+
PyObject *dict = PyThreadState_GetDict();
1247+
assert(dict != NULL);
1248+
// dict is a borrowed reference
1249+
1250+
PyObject *dict2 = _PyThreadState_GetDict(tstate);
1251+
assert(dict2 == dict);
1252+
// dict2 is a borrowed reference
1253+
1254+
Py_RETURN_NONE;
1255+
}
1256+
1257+
12371258
static PyMethodDef module_functions[] = {
12381259
{"get_configs", get_configs, METH_NOARGS},
12391260
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -1284,6 +1305,7 @@ static PyMethodDef module_functions[] = {
12841305
{"_PyTime_ObjectToTimespec", test_pytime_object_to_timespec, METH_VARARGS},
12851306
{"_PyTime_ObjectToTimeval", test_pytime_object_to_timeval, METH_VARARGS},
12861307
{"_PyTraceMalloc_GetTraceback", tracemalloc_get_traceback, METH_VARARGS},
1308+
{"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
12871309
{NULL, NULL} /* sentinel */
12881310
};
12891311

Modules/_xxsubinterpretersmodule.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
21
/* interpreters module */
32
/* low-level access to interpreter primitives */
43

4+
#ifndef Py_BUILD_CORE_BUILTIN
5+
# define Py_BUILD_CORE_MODULE 1
6+
#endif
7+
58
#include "Python.h"
9+
#include "pycore_interp.h" // _PyInterpreterState_GetMainModule()
610
#include "interpreteridobject.h"
711

812

Python/compile.c

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "pycore_compile.h"
3434
#include "pycore_intrinsics.h"
3535
#include "pycore_long.h" // _PyLong_GetZero()
36+
#include "pycore_pystate.h" // _Py_GetConfig()
3637
#include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST()
3738

3839
#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed

Python/frozenmain.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* Python interpreter main program for frozen scripts */
22

33
#include "Python.h"
4-
#include "pycore_runtime.h" // _PyRuntime_Initialize()
4+
#include "pycore_pystate.h" // _Py_GetConfig()
5+
#include "pycore_runtime.h" // _PyRuntime_Initialize()
56
#include <locale.h>
67

78
#ifdef MS_WINDOWS

Python/pystate.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ PyInterpreterState_GetDict(PyInterpreterState *interp)
11661166
The GIL must be held.
11671167
*/
11681168

1169-
PyInterpreterState *
1169+
PyInterpreterState*
11701170
PyInterpreterState_Get(void)
11711171
{
11721172
PyThreadState *tstate = current_fast_get(&_PyRuntime);
@@ -1408,15 +1408,15 @@ _PyThreadState_New(PyInterpreterState *interp)
14081408
}
14091409

14101410
// We keep this for stable ABI compabibility.
1411-
PyThreadState *
1411+
PyAPI_FUNC(PyThreadState*)
14121412
_PyThreadState_Prealloc(PyInterpreterState *interp)
14131413
{
14141414
return _PyThreadState_New(interp);
14151415
}
14161416

14171417
// We keep this around for (accidental) stable ABI compatibility.
14181418
// Realistically, no extensions are using it.
1419-
void
1419+
PyAPI_FUNC(void)
14201420
_PyThreadState_Init(PyThreadState *tstate)
14211421
{
14221422
Py_FatalError("_PyThreadState_Init() is for internal use only");

0 commit comments

Comments
 (0)