Skip to content

Commit 7fedbc0

Browse files
Add is_running().
1 parent 9cde3ec commit 7fedbc0

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

Doc/library/_interpreters.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ It defines the following functions:
4141
Return the ID of the currently running interpreter.
4242

4343

44+
.. function:: is_running(id)
45+
46+
Return whether or not the identified interpreter is currently
47+
running any code.
48+
49+
4450
.. function:: create()
4551

4652
Initialize a new Python interpreter and return its identifier. The

Lib/test/test__interpreters.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,36 @@ def test_sub(self):
111111
self.assertEqual(id2, id1)
112112

113113

114+
class IsRunningTests(TestBase):
115+
116+
def test_main_running(self):
117+
main, = interpreters.enumerate()
118+
sub = interpreters.create()
119+
main_running = interpreters.is_running(main)
120+
sub_running = interpreters.is_running(sub)
121+
122+
self.assertTrue(main_running)
123+
self.assertFalse(sub_running)
124+
125+
def test_sub_running(self):
126+
main, = interpreters.enumerate()
127+
sub1 = interpreters.create()
128+
sub2 = interpreters.create()
129+
ns = interpreters.run_string_unrestricted(sub1, dedent(f"""
130+
import _interpreters
131+
main = _interpreters.is_running({main})
132+
sub1 = _interpreters.is_running({sub1})
133+
sub2 = _interpreters.is_running({sub2})
134+
"""))
135+
main_running = ns['main']
136+
sub1_running = ns['sub1']
137+
sub2_running = ns['sub2']
138+
139+
self.assertTrue(main_running)
140+
self.assertTrue(sub1_running)
141+
self.assertFalse(sub2_running)
142+
143+
114144
class CreateTests(TestBase):
115145

116146
def test_in_main(self):

Modules/_interpretersmodule.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,34 @@ merged into the execution namespace before the code is executed.\n\
417417
See PyRun_SimpleStrings.");
418418

419419

420+
static PyObject *
421+
interp_is_running(PyObject *self, PyObject *args)
422+
{
423+
PyObject *id;
424+
if (!PyArg_UnpackTuple(args, "is_running", 1, 1, &id))
425+
return NULL;
426+
if (!PyLong_Check(id)) {
427+
PyErr_SetString(PyExc_TypeError, "ID must be an int");
428+
return NULL;
429+
}
430+
431+
PyInterpreterState *interp = _look_up(id);
432+
if (interp == NULL)
433+
return NULL;
434+
int is_running = _is_running(interp);
435+
if (is_running < 0)
436+
return NULL;
437+
if (is_running)
438+
Py_RETURN_TRUE;
439+
Py_RETURN_FALSE;
440+
}
441+
442+
PyDoc_STRVAR(is_running_doc,
443+
"is_running(id) -> bool\n\
444+
\n\
445+
Return whether or not the identified interpreter is running.");
446+
447+
420448
static PyMethodDef module_functions[] = {
421449
{"create", (PyCFunction)interp_create,
422450
METH_VARARGS, create_doc},
@@ -427,6 +455,8 @@ static PyMethodDef module_functions[] = {
427455
METH_NOARGS, enumerate_doc},
428456
{"get_current", (PyCFunction)interp_get_current,
429457
METH_NOARGS, get_current_doc},
458+
{"is_running", (PyCFunction)interp_is_running,
459+
METH_VARARGS, is_running_doc},
430460

431461
{"run_string", (PyCFunction)interp_run_string,
432462
METH_VARARGS, run_string_doc},

0 commit comments

Comments
 (0)