(original) (raw)
changeset: 74471:eb47af6e9e22 branch: 3.2 parent: 74465:f715c4a5a107 user: Antoine Pitrou solipsis@pitrou.net date: Wed Jan 18 00:21:11 2012 +0100 files: Lib/test/test_capi.py Modules/_testcapimodule.c description: Test running of code in a sub-interpreter (prelude to issue #6531). diff -r f715c4a5a107 -r eb47af6e9e22 Lib/test/test_capi.py --- a/Lib/test/test_capi.py Tue Jan 17 17:13:04 2012 +0100 +++ b/Lib/test/test_capi.py Wed Jan 18 00:21:11 2012 +0100 @@ -3,6 +3,7 @@ from __future__ import with_statement import os +import pickle import random import subprocess import sys @@ -137,6 +138,22 @@ 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): diff -r f715c4a5a107 -r eb47af6e9e22 Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Tue Jan 17 17:13:04 2012 +0100 +++ b/Modules/_testcapimodule.c Wed Jan 18 00:21:11 2012 +0100 @@ -2300,6 +2300,32 @@ 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 @@ {"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 */ }; /solipsis@pitrou.net