summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/support/interpreters.py18
-rw-r--r--Lib/test/test__xxsubinterpreters.py105
2 files changed, 121 insertions, 2 deletions
diff --git a/Lib/test/support/interpreters.py b/Lib/test/support/interpreters.py
index 3b50161..5aba369 100644
--- a/Lib/test/support/interpreters.py
+++ b/Lib/test/support/interpreters.py
@@ -91,12 +91,26 @@ class Interpreter:
"""
return _interpreters.destroy(self._id)
+ # XXX Rename "run" to "exec"?
def run(self, src_str, /, *, channels=None):
"""Run the given source code in the interpreter.
- This blocks the current Python thread until done.
+ This is essentially the same as calling the builtin "exec"
+ with this interpreter, using the __dict__ of its __main__
+ module as both globals and locals.
+
+ There is no return value.
+
+ If the code raises an unhandled exception then a RunFailedError
+ is raised, which summarizes the unhandled exception. The actual
+ exception is discarded because objects cannot be shared between
+ interpreters.
+
+ This blocks the current Python thread until done. During
+ that time, the previous interpreter is allowed to run
+ in other threads.
"""
- _interpreters.run_string(self._id, src_str, channels)
+ _interpreters.exec(self._id, src_str, channels)
def create_channel():
diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py
index ac2280e..e3c917a 100644
--- a/Lib/test/test__xxsubinterpreters.py
+++ b/Lib/test/test__xxsubinterpreters.py
@@ -925,5 +925,110 @@ class RunStringTests(TestBase):
self.assertEqual(retcode, 0)
+class RunFuncTests(TestBase):
+
+ def setUp(self):
+ super().setUp()
+ self.id = interpreters.create()
+
+ def test_success(self):
+ r, w = os.pipe()
+ def script():
+ global w
+ import contextlib
+ with open(w, 'w', encoding="utf-8") as spipe:
+ with contextlib.redirect_stdout(spipe):
+ print('it worked!', end='')
+ interpreters.run_func(self.id, script, shared=dict(w=w))
+
+ with open(r, encoding="utf-8") as outfile:
+ out = outfile.read()
+
+ self.assertEqual(out, 'it worked!')
+
+ def test_in_thread(self):
+ r, w = os.pipe()
+ def script():
+ global w
+ import contextlib
+ with open(w, 'w', encoding="utf-8") as spipe:
+ with contextlib.redirect_stdout(spipe):
+ print('it worked!', end='')
+ def f():
+ interpreters.run_func(self.id, script, shared=dict(w=w))
+ t = threading.Thread(target=f)
+ t.start()
+ t.join()
+
+ with open(r, encoding="utf-8") as outfile:
+ out = outfile.read()
+
+ self.assertEqual(out, 'it worked!')
+
+ def test_code_object(self):
+ r, w = os.pipe()
+
+ def script():
+ global w
+ import contextlib
+ with open(w, 'w', encoding="utf-8") as spipe:
+ with contextlib.redirect_stdout(spipe):
+ print('it worked!', end='')
+ code = script.__code__
+ interpreters.run_func(self.id, code, shared=dict(w=w))
+
+ with open(r, encoding="utf-8") as outfile:
+ out = outfile.read()
+
+ self.assertEqual(out, 'it worked!')
+
+ def test_closure(self):
+ spam = True
+ def script():
+ assert spam
+
+ with self.assertRaises(ValueError):
+ interpreters.run_func(self.id, script)
+
+ # XXX This hasn't been fixed yet.
+ @unittest.expectedFailure
+ def test_return_value(self):
+ def script():
+ return 'spam'
+ with self.assertRaises(ValueError):
+ interpreters.run_func(self.id, script)
+
+ def test_args(self):
+ with self.subTest('args'):
+ def script(a, b=0):
+ assert a == b
+ with self.assertRaises(ValueError):
+ interpreters.run_func(self.id, script)
+
+ with self.subTest('*args'):
+ def script(*args):
+ assert not args
+ with self.assertRaises(ValueError):
+ interpreters.run_func(self.id, script)
+
+ with self.subTest('**kwargs'):
+ def script(**kwargs):
+ assert not kwargs
+ with self.assertRaises(ValueError):
+ interpreters.run_func(self.id, script)
+
+ with self.subTest('kwonly'):
+ def script(*, spam=True):
+ assert spam
+ with self.assertRaises(ValueError):
+ interpreters.run_func(self.id, script)
+
+ with self.subTest('posonly'):
+ def script(spam, /):
+ assert spam
+ with self.assertRaises(ValueError):
+ interpreters.run_func(self.id, script)
+
+
if __name__ == '__main__':
unittest.main()