Test running of code in a sub-interpreter

(prelude to issue #6531).
This commit is contained in:
Antoine Pitrou 2012-01-18 00:21:11 +01:00
parent 03757ec4a5
commit 2f828f2c88
2 changed files with 44 additions and 0 deletions

View File

@ -3,6 +3,7 @@
from __future__ import with_statement
import os
import pickle
import random
import subprocess
import sys
@ -137,6 +138,22 @@ class TestPendingCalls(unittest.TestCase):
self.pendingcalls_submit(l, n)
self.pendingcalls_wait(l, n)
def test_subinterps(self):
# XXX this test leaks in refleak runs
import builtins
r, w = os.pipe()
code = """if 1:
import sys, builtins, pickle
with open({:d}, "wb") as f:
pickle.dump(id(sys.modules), f)
pickle.dump(id(builtins), f)
""".format(w)
with open(r, "rb") as f:
ret = _testcapi.run_in_subinterp(code)
self.assertEqual(ret, 0)
self.assertNotEqual(pickle.load(f), id(sys.modules))
self.assertNotEqual(pickle.load(f), id(builtins))
# Bug #6012
class Test6012(unittest.TestCase):
def test(self):

View File

@ -2300,6 +2300,32 @@ crash_no_current_thread(PyObject *self)
return NULL;
}
/* To run some code in a sub-interpreter. */
static PyObject *
run_in_subinterp(PyObject *self, PyObject *args)
{
const char *code;
int r;
PyThreadState *substate, *mainstate;
if (!PyArg_ParseTuple(args, "s:run_in_subinterp",
&code))
return NULL;
mainstate = PyThreadState_Get();
PyThreadState_Swap(NULL);
substate = Py_NewInterpreter();
r = PyRun_SimpleString(code);
Py_EndInterpreter(substate);
PyThreadState_Swap(mainstate);
return PyLong_FromLong(r);
}
static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
{"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS},
@ -2385,6 +2411,7 @@ static PyMethodDef TestMethods[] = {
{"make_memoryview_from_NULL_pointer", (PyCFunction)make_memoryview_from_NULL_pointer,
METH_NOARGS},
{"crash_no_current_thread", (PyCFunction)crash_no_current_thread, METH_NOARGS},
{"run_in_subinterp", run_in_subinterp, METH_VARARGS},
{NULL, NULL} /* sentinel */
};