Skip to content

Commit c50c51c

Browse files
Add is_running().
1 parent ab8f175 commit c50c51c

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
@@ -533,6 +533,34 @@ Return True if the object's data may be shared between interpreters and\n\
533533
False otherwise.");
534534

535535

536+
static PyObject *
537+
interp_is_running(PyObject *self, PyObject *args)
538+
{
539+
PyObject *id;
540+
if (!PyArg_UnpackTuple(args, "is_running", 1, 1, &id))
541+
return NULL;
542+
if (!PyLong_Check(id)) {
543+
PyErr_SetString(PyExc_TypeError, "ID must be an int");
544+
return NULL;
545+
}
546+
547+
PyInterpreterState *interp = _look_up(id);
548+
if (interp == NULL)
549+
return NULL;
550+
int is_running = _is_running(interp);
551+
if (is_running < 0)
552+
return NULL;
553+
if (is_running)
554+
Py_RETURN_TRUE;
555+
Py_RETURN_FALSE;
556+
}
557+
558+
PyDoc_STRVAR(is_running_doc,
559+
"is_running(id) -> bool\n\
560+
\n\
561+
Return whether or not the identified interpreter is running.");
562+
563+
536564
static PyMethodDef module_functions[] = {
537565
{"create", (PyCFunction)interp_create,
538566
METH_VARARGS, create_doc},
@@ -543,6 +571,8 @@ static PyMethodDef module_functions[] = {
543571
METH_NOARGS, enumerate_doc},
544572
{"get_current", (PyCFunction)interp_get_current,
545573
METH_NOARGS, get_current_doc},
574+
{"is_running", (PyCFunction)interp_is_running,
575+
METH_VARARGS, is_running_doc},
546576

547577
{"run_string", (PyCFunction)interp_run_string,
548578
METH_VARARGS, run_string_doc},

0 commit comments

Comments
 (0)