Skip to content

Commit cd7d5ee

Browse files
Require the interpreter to be ready for most operations.
1 parent fe362d1 commit cd7d5ee

File tree

4 files changed

+56
-16
lines changed

4 files changed

+56
-16
lines changed

Include/internal/pycore_interp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *);
317317
PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *);
318318
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *);
319319

320+
PyAPI_FUNC(int) _PyInterpreterState_IsReady(PyInterpreterState *interp);
321+
320322
PyAPI_FUNC(long) _PyInterpreterState_GetWhence(PyInterpreterState *interp);
321323
extern void _PyInterpreterState_SetWhence(
322324
PyInterpreterState *interp,

Modules/_xxsubinterpretersmodule.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ get_whence(PyInterpreterState *interp)
499499

500500

501501
static PyInterpreterState *
502-
resolve_interp(PyObject *idobj, int restricted, const char *op)
502+
resolve_interp(PyObject *idobj, int restricted, int reqready, const char *op)
503503
{
504504
PyInterpreterState *interp;
505505
if (idobj == NULL) {
@@ -512,6 +512,18 @@ resolve_interp(PyObject *idobj, int restricted, const char *op)
512512
}
513513
}
514514

515+
if (reqready && !_PyInterpreterState_IsReady(interp)) {
516+
if (idobj == NULL) {
517+
PyErr_Format(PyExc_InterpreterError,
518+
"cannot %s current interpreter (not ready)", op);
519+
}
520+
else {
521+
PyErr_Format(PyExc_InterpreterError,
522+
"cannot %s interpreter %R (not ready)", op, idobj);
523+
}
524+
return NULL;
525+
}
526+
515527
if (restricted && get_whence(interp) != _PyInterpreterState_WHENCE_STDLIB) {
516528
if (idobj == NULL) {
517529
PyErr_Format(PyExc_InterpreterError,
@@ -619,6 +631,7 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds)
619631
_PyErr_ChainExceptions1(exc);
620632
return NULL;
621633
}
634+
assert(_PyInterpreterState_IsReady(interp));
622635

623636
PyObject *idobj = _PyInterpreterState_GetIDObject(interp);
624637
if (idobj == NULL) {
@@ -664,7 +677,9 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds)
664677
}
665678

666679
// Look up the interpreter.
667-
PyInterpreterState *interp = resolve_interp(id, restricted, "destroy");
680+
int reqready = 0;
681+
PyInterpreterState *interp = \
682+
resolve_interp(id, restricted, reqready, "destroy");
668683
if (interp == NULL) {
669684
return NULL;
670685
}
@@ -746,6 +761,7 @@ interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored))
746761
if (interp == NULL) {
747762
return NULL;
748763
}
764+
assert(_PyInterpreterState_IsReady(interp));
749765
return get_summary(interp);
750766
}
751767

@@ -759,6 +775,7 @@ static PyObject *
759775
interp_get_main(PyObject *self, PyObject *Py_UNUSED(ignored))
760776
{
761777
PyInterpreterState *interp = _PyInterpreterState_Main();
778+
assert(_PyInterpreterState_IsReady(interp));
762779
return get_summary(interp);
763780
}
764781

@@ -782,8 +799,9 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
782799
}
783800

784801
// Look up the interpreter.
785-
PyInterpreterState *interp = resolve_interp(id, restricted,
786-
"update __main__ for");
802+
int reqready = 1;
803+
PyInterpreterState *interp = \
804+
resolve_interp(id, restricted, reqready, "update __main__ for");
787805
if (interp == NULL) {
788806
return NULL;
789807
}
@@ -942,7 +960,9 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
942960
return NULL;
943961
}
944962

945-
PyInterpreterState *interp = resolve_interp(id, restricted, "exec code for");
963+
int reqready = 1;
964+
PyInterpreterState *interp = \
965+
resolve_interp(id, restricted, reqready, "exec code for");
946966
if (interp == NULL) {
947967
return NULL;
948968
}
@@ -1004,7 +1024,9 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
10041024
return NULL;
10051025
}
10061026

1007-
PyInterpreterState *interp = resolve_interp(id, restricted, "make a call in");
1027+
int reqready = 1;
1028+
PyInterpreterState *interp = \
1029+
resolve_interp(id, restricted, reqready, "make a call in");
10081030
if (interp == NULL) {
10091031
return NULL;
10101032
}
@@ -1060,7 +1082,9 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
10601082
return NULL;
10611083
}
10621084

1063-
PyInterpreterState *interp = resolve_interp(id, restricted, "run a string in");
1085+
int reqready = 1;
1086+
PyInterpreterState *interp = \
1087+
resolve_interp(id, restricted, reqready, "run a string in");
10641088
if (interp == NULL) {
10651089
return NULL;
10661090
}
@@ -1102,8 +1126,9 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
11021126
return NULL;
11031127
}
11041128

1105-
PyInterpreterState *interp = resolve_interp(id, restricted,
1106-
"run a function in");
1129+
int reqready = 1;
1130+
PyInterpreterState *interp = \
1131+
resolve_interp(id, restricted, reqready, "run a function in");
11071132
if (interp == NULL) {
11081133
return NULL;
11091134
}
@@ -1172,8 +1197,9 @@ interp_is_running(PyObject *self, PyObject *args, PyObject *kwds)
11721197
return NULL;
11731198
}
11741199

1175-
PyInterpreterState *interp = resolve_interp(id, restricted,
1176-
"check if running for");
1200+
int reqready = 1;
1201+
PyInterpreterState *interp = \
1202+
resolve_interp(id, restricted, reqready, "check if running for");
11771203
if (interp == NULL) {
11781204
return NULL;
11791205
}
@@ -1206,8 +1232,9 @@ interp_get_config(PyObject *self, PyObject *args, PyObject *kwds)
12061232
idobj = NULL;
12071233
}
12081234

1209-
PyInterpreterState *interp = resolve_interp(idobj, restricted,
1210-
"get the config of");
1235+
int reqready = 0;
1236+
PyInterpreterState *interp = \
1237+
resolve_interp(idobj, restricted, reqready, "get the config of");
12111238
if (interp == NULL) {
12121239
return NULL;
12131240
}
@@ -1272,7 +1299,9 @@ interp_incref(PyObject *self, PyObject *args, PyObject *kwds)
12721299
return NULL;
12731300
}
12741301

1275-
PyInterpreterState *interp = resolve_interp(id, restricted, "incref");
1302+
int reqready = 1;
1303+
PyInterpreterState *interp = \
1304+
resolve_interp(id, restricted, reqready, "incref");
12761305
if (interp == NULL) {
12771306
return NULL;
12781307
}
@@ -1299,7 +1328,9 @@ interp_decref(PyObject *self, PyObject *args, PyObject *kwds)
12991328
return NULL;
13001329
}
13011330

1302-
PyInterpreterState *interp = resolve_interp(id, restricted, "decref");
1331+
int reqready = 1;
1332+
PyInterpreterState *interp = \
1333+
resolve_interp(id, restricted, reqready, "decref");
13031334
if (interp == NULL) {
13041335
return NULL;
13051336
}

Python/crossinterp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,7 @@ _PyXI_EndInterpreter(PyInterpreterState *interp,
18961896
long whence = _PyInterpreterState_GetWhence(interp);
18971897
assert(whence != _PyInterpreterState_WHENCE_RUNTIME);
18981898
if (whence == _PyInterpreterState_WHENCE_UNKNOWN) {
1899-
assert(!interp->_ready);
1899+
assert(!_PyInterpreterState_IsReady(interp));
19001900
PyThreadState *tstate = PyThreadState_New(interp);
19011901
save_tstate = PyThreadState_Swap(tstate);
19021902
_PyInterpreterState_Clear(tstate);

Python/pystate.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,13 @@ _PyInterpreterState_ReinitRunningMain(PyThreadState *tstate)
11111111
// accessors
11121112
//----------
11131113

1114+
int
1115+
_PyInterpreterState_IsReady(PyInterpreterState *interp)
1116+
{
1117+
return interp->_ready;
1118+
}
1119+
1120+
11141121
static inline int
11151122
check_interpreter_whence(long whence)
11161123
{

0 commit comments

Comments
 (0)