diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2012-04-18 22:57:45 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2012-04-18 22:57:45 (GMT) |
commit | b0b224233e481d979430a54d257d871424ff19fb (patch) | |
tree | 86be7f1a45404ec56003f36f5f76dd82c85c6ca8 /Lib/test/test_builtin.py | |
parent | 05fac022eca4604275e16c62136ca02aaea879e1 (diff) | |
download | cpython-b0b224233e481d979430a54d257d871424ff19fb.zip cpython-b0b224233e481d979430a54d257d871424ff19fb.tar.gz cpython-b0b224233e481d979430a54d257d871424ff19fb.tar.bz2 |
Issue #14385: Support other types than dict for __builtins__
It is now possible to use a custom type for the __builtins__ namespace, instead
of a dict. It can be used for sandboxing for example. Raise also a NameError
instead of ImportError if __build_class__ name if not found in __builtins__.
Diffstat (limited to 'Lib/test/test_builtin.py')
-rw-r--r-- | Lib/test/test_builtin.py | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 88bccd9..dfe64bf 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -554,6 +554,39 @@ class BuiltinTest(unittest.TestCase): del l['__builtins__'] self.assertEqual((g, l), ({'a': 1}, {'b': 2})) + def test_exec_globals(self): + code = compile("print('Hello World!')", "", "exec") + # no builtin function + self.assertRaisesRegex(NameError, "name 'print' is not defined", + exec, code, {'__builtins__': {}}) + # __builtins__ must be a mapping type + self.assertRaises(TypeError, + exec, code, {'__builtins__': 123}) + + # no __build_class__ function + code = compile("class A: pass", "", "exec") + self.assertRaisesRegex(NameError, "__build_class__ not found", + exec, code, {'__builtins__': {}}) + + class frozendict_error(Exception): + pass + + class frozendict(dict): + def __setitem__(self, key, value): + raise frozendict_error("frozendict is readonly") + + # read-only builtins + frozen_builtins = frozendict(__builtins__) + code = compile("__builtins__['superglobal']=2; print(superglobal)", "test", "exec") + self.assertRaises(frozendict_error, + exec, code, {'__builtins__': frozen_builtins}) + + # read-only globals + namespace = frozendict({}) + code = compile("x=1", "test", "exec") + self.assertRaises(frozendict_error, + exec, code, namespace) + def test_exec_redirected(self): savestdout = sys.stdout sys.stdout = None # Whatever that cannot flush() |