summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2012-04-18 22:57:45 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2012-04-18 22:57:45 (GMT)
commitb0b224233e481d979430a54d257d871424ff19fb (patch)
tree86be7f1a45404ec56003f36f5f76dd82c85c6ca8 /Lib
parent05fac022eca4604275e16c62136ca02aaea879e1 (diff)
downloadcpython-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')
-rw-r--r--Lib/test/test_builtin.py33
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()