Skip to content

Commit 8bdae14

Browse files
gh-101524: Only Use Public C-API in the _xxsubinterpreters Module (gh-107359)
The _xxsubinterpreters module should not rely on internal API. Some of the functions it uses were recently moved there however. Here we move them back (and expose them properly).
1 parent 75c974f commit 8bdae14

18 files changed

+80
-82
lines changed

Include/cpython/interpreteridobject.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef Py_CPYTHON_INTERPRETERIDOBJECT_H
2+
# error "this header file must not be included directly"
3+
#endif
4+
5+
/* Interpreter ID Object */
6+
7+
PyAPI_DATA(PyTypeObject) PyInterpreterID_Type;
8+
9+
PyAPI_FUNC(PyObject *) PyInterpreterID_New(int64_t);
10+
PyAPI_FUNC(PyObject *) PyInterpreterState_GetIDObject(PyInterpreterState *);
11+
PyAPI_FUNC(PyInterpreterState *) PyInterpreterID_LookUp(PyObject *);

Include/cpython/pylifecycle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,7 @@ typedef struct {
7777
PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig(
7878
PyThreadState **tstate_p,
7979
const PyInterpreterConfig *config);
80+
81+
typedef void (*atexit_datacallbackfunc)(void *);
82+
PyAPI_FUNC(int) PyUnstable_AtExit(
83+
PyInterpreterState *, atexit_datacallbackfunc, void *);

Include/cpython/pystate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
99
PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int);
1010

11+
PyAPI_FUNC(PyObject *) PyUnstable_InterpreterState_GetMainModule(PyInterpreterState *);
1112

1213
/* State unique per thread */
1314

Include/internal/pycore_interp.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,6 @@ extern int _PyInterpreterState_IDInitref(PyInterpreterState *);
238238
extern int _PyInterpreterState_IDIncref(PyInterpreterState *);
239239
extern void _PyInterpreterState_IDDecref(PyInterpreterState *);
240240

241-
// Export for '_xxsubinterpreters' shared extension
242-
PyAPI_FUNC(PyObject*) _PyInterpreterState_GetMainModule(PyInterpreterState *);
243-
244241
extern const PyConfig* _PyInterpreterState_GetConfig(PyInterpreterState *interp);
245242

246243
/* Get a copy of the current interpreter configuration.

Include/internal/pycore_interp_id.h

Lines changed: 0 additions & 28 deletions
This file was deleted.

Include/interpreteridobject.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef Py_INTERPRETERIDOBJECT_H
2+
#define Py_INTERPRETERIDOBJECT_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
#ifndef Py_LIMITED_API
9+
# define Py_CPYTHON_INTERPRETERIDOBJECT_H
10+
# include "cpython/interpreteridobject.h"
11+
# undef Py_CPYTHON_INTERPRETERIDOBJECT_H
12+
#endif
13+
14+
#ifdef __cplusplus
15+
}
16+
#endif
17+
#endif /* !Py_INTERPRETERIDOBJECT_H */

Makefile.pre.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,7 @@ PYTHON_HEADERS= \
16311631
$(srcdir)/Include/floatobject.h \
16321632
$(srcdir)/Include/frameobject.h \
16331633
$(srcdir)/Include/import.h \
1634+
$(srcdir)/Include/interpreteridobject.h \
16341635
$(srcdir)/Include/intrcheck.h \
16351636
$(srcdir)/Include/iterobject.h \
16361637
$(srcdir)/Include/listobject.h \
@@ -1700,6 +1701,7 @@ PYTHON_HEADERS= \
17001701
$(srcdir)/Include/cpython/genobject.h \
17011702
$(srcdir)/Include/cpython/import.h \
17021703
$(srcdir)/Include/cpython/initconfig.h \
1704+
$(srcdir)/Include/cpython/interpreteridobject.h \
17031705
$(srcdir)/Include/cpython/listobject.h \
17041706
$(srcdir)/Include/cpython/longintrepr.h \
17051707
$(srcdir)/Include/cpython/longobject.h \
@@ -1771,7 +1773,6 @@ PYTHON_HEADERS= \
17711773
$(srcdir)/Include/internal/pycore_import.h \
17721774
$(srcdir)/Include/internal/pycore_initconfig.h \
17731775
$(srcdir)/Include/internal/pycore_interp.h \
1774-
$(srcdir)/Include/internal/pycore_interp_id.h \
17751776
$(srcdir)/Include/internal/pycore_intrinsics.h \
17761777
$(srcdir)/Include/internal/pycore_list.h \
17771778
$(srcdir)/Include/internal/pycore_long.h \

Modules/_testinternalcapi.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,27 @@
1313
#include "pycore_atomic_funcs.h" // _Py_atomic_int_get()
1414
#include "pycore_bitutils.h" // _Py_bswap32()
1515
#include "pycore_bytesobject.h" // _PyBytes_Find()
16-
#include "pycore_ceval.h" // _PyEval_AddPendingCall
1716
#include "pycore_compile.h" // _PyCompile_CodeGen, _PyCompile_OptimizeCfg, _PyCompile_Assemble, _PyCompile_CleanDoc
17+
#include "pycore_ceval.h" // _PyEval_AddPendingCall
1818
#include "pycore_fileutils.h" // _Py_normpath
1919
#include "pycore_frame.h" // _PyInterpreterFrame
2020
#include "pycore_gc.h" // PyGC_Head
2121
#include "pycore_hashtable.h" // _Py_hashtable_new()
2222
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
2323
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
24-
#include "pycore_interp_id.h" // _PyInterpreterID_LookUp()
25-
#include "pycore_object.h" // _PyObject_IsFreed()
24+
#include "pycore_object.h" // _PyObject_IsFreed()
2625
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
2726
#include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost()
2827
#include "pycore_pystate.h" // _PyThreadState_GET()
2928

3029
#include "frameobject.h"
30+
#include "interpreteridobject.h" // PyInterpreterID_LookUp()
3131
#include "osdefs.h" // MAXPATHLEN
3232

3333
#include "clinic/_testinternalcapi.c.h"
3434

3535
#ifdef MS_WINDOWS
36-
# include <winsock2.h> // struct timeval
36+
# include <winsock2.h> // struct timeval
3737
#endif
3838

3939

@@ -1083,7 +1083,7 @@ pending_identify(PyObject *self, PyObject *args)
10831083
if (!PyArg_ParseTuple(args, "O:pending_identify", &interpid)) {
10841084
return NULL;
10851085
}
1086-
PyInterpreterState *interp = _PyInterpreterID_LookUp(interpid);
1086+
PyInterpreterState *interp = PyInterpreterID_LookUp(interpid);
10871087
if (interp == NULL) {
10881088
if (!PyErr_Occurred()) {
10891089
PyErr_SetString(PyExc_ValueError, "interpreter not found");
@@ -1433,7 +1433,7 @@ test_atexit(PyObject *self, PyObject *Py_UNUSED(args))
14331433
PyThreadState *tstate = Py_NewInterpreter();
14341434

14351435
struct atexit_data data = {0};
1436-
int res = _Py_AtExit(tstate->interp, callback, (void *)&data);
1436+
int res = PyUnstable_AtExit(tstate->interp, callback, (void *)&data);
14371437
Py_EndInterpreter(tstate);
14381438
PyThreadState_Swap(oldts);
14391439
if (res < 0) {

Modules/_xxinterpchannelsmodule.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
/* interpreters module */
22
/* low-level access to interpreter primitives */
33

4-
#ifndef Py_BUILD_CORE_BUILTIN
5-
# define Py_BUILD_CORE_MODULE 1
6-
#endif
7-
84
#include "Python.h"
9-
#include "pycore_atexit.h" // _Py_AtExit()
10-
#include "pycore_interp_id.h" // _PyInterpreterState_GetIDObject()
5+
#include "interpreteridobject.h"
116

127

138
/*
@@ -2140,7 +2135,7 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds)
21402135
goto except;
21412136
}
21422137
if (res) {
2143-
id_obj = _PyInterpreterState_GetIDObject(interp);
2138+
id_obj = PyInterpreterState_GetIDObject(interp);
21442139
if (id_obj == NULL) {
21452140
goto except;
21462141
}
@@ -2407,7 +2402,7 @@ module_exec(PyObject *mod)
24072402

24082403
// Make sure chnnels drop objects owned by this interpreter
24092404
PyInterpreterState *interp = _get_current_interp();
2410-
_Py_AtExit(interp, clear_interpreter, (void *)interp);
2405+
PyUnstable_AtExit(interp, clear_interpreter, (void *)interp);
24112406

24122407
return 0;
24132408

Modules/_xxsubinterpretersmodule.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
/* interpreters module */
22
/* low-level access to interpreter primitives */
33

4-
#ifndef Py_BUILD_CORE_BUILTIN
5-
# define Py_BUILD_CORE_MODULE 1
6-
#endif
7-
84
#include "Python.h"
9-
#include "pycore_interp.h" // _PyInterpreterState_GetMainModule()
10-
#include "pycore_interp_id.h" // _PyInterpreterState_GetIDObject()
5+
#include "interpreteridobject.h"
116

127

138
#define MODULE_NAME "_xxsubinterpreters"
@@ -400,7 +395,7 @@ _run_script(PyInterpreterState *interp, const char *codestr,
400395
_sharedns *shared, _sharedexception *sharedexc)
401396
{
402397
PyObject *excval = NULL;
403-
PyObject *main_mod = _PyInterpreterState_GetMainModule(interp);
398+
PyObject *main_mod = PyUnstable_InterpreterState_GetMainModule(interp);
404399
if (main_mod == NULL) {
405400
goto error;
406401
}
@@ -531,7 +526,7 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds)
531526
}
532527
assert(tstate != NULL);
533528
PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate);
534-
PyObject *idobj = _PyInterpreterState_GetIDObject(interp);
529+
PyObject *idobj = PyInterpreterState_GetIDObject(interp);
535530
if (idobj == NULL) {
536531
// XXX Possible GILState issues?
537532
save_tstate = PyThreadState_Swap(tstate);
@@ -561,7 +556,7 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds)
561556
}
562557

563558
// Look up the interpreter.
564-
PyInterpreterState *interp = _PyInterpreterID_LookUp(id);
559+
PyInterpreterState *interp = PyInterpreterID_LookUp(id);
565560
if (interp == NULL) {
566561
return NULL;
567562
}
@@ -616,7 +611,7 @@ interp_list_all(PyObject *self, PyObject *Py_UNUSED(ignored))
616611

617612
interp = PyInterpreterState_Head();
618613
while (interp != NULL) {
619-
id = _PyInterpreterState_GetIDObject(interp);
614+
id = PyInterpreterState_GetIDObject(interp);
620615
if (id == NULL) {
621616
Py_DECREF(ids);
622617
return NULL;
@@ -648,7 +643,7 @@ interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored))
648643
if (interp == NULL) {
649644
return NULL;
650645
}
651-
return _PyInterpreterState_GetIDObject(interp);
646+
return PyInterpreterState_GetIDObject(interp);
652647
}
653648

654649
PyDoc_STRVAR(get_current_doc,
@@ -662,7 +657,7 @@ interp_get_main(PyObject *self, PyObject *Py_UNUSED(ignored))
662657
{
663658
// Currently, 0 is always the main interpreter.
664659
int64_t id = 0;
665-
return _PyInterpreterID_New(id);
660+
return PyInterpreterID_New(id);
666661
}
667662

668663
PyDoc_STRVAR(get_main_doc,
@@ -684,7 +679,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
684679
}
685680

686681
// Look up the interpreter.
687-
PyInterpreterState *interp = _PyInterpreterID_LookUp(id);
682+
PyInterpreterState *interp = PyInterpreterID_LookUp(id);
688683
if (interp == NULL) {
689684
return NULL;
690685
}
@@ -750,7 +745,7 @@ interp_is_running(PyObject *self, PyObject *args, PyObject *kwds)
750745
return NULL;
751746
}
752747

753-
PyInterpreterState *interp = _PyInterpreterID_LookUp(id);
748+
PyInterpreterState *interp = PyInterpreterID_LookUp(id);
754749
if (interp == NULL) {
755750
return NULL;
756751
}
@@ -808,7 +803,7 @@ module_exec(PyObject *mod)
808803
}
809804

810805
// PyInterpreterID
811-
if (PyModule_AddType(mod, &_PyInterpreterID_Type) < 0) {
806+
if (PyModule_AddType(mod, &PyInterpreterID_Type) < 0) {
812807
goto error;
813808
}
814809

0 commit comments

Comments
 (0)