@@ -737,6 +737,7 @@ def test_exec_globals(self):
737
737
self .assertRaises (TypeError ,
738
738
exec , code , {'__builtins__' : 123 })
739
739
740
+ def test_exec_globals_frozen (self ):
740
741
class frozendict_error (Exception ):
741
742
pass
742
743
@@ -768,6 +769,36 @@ def __setitem__(self, key, value):
768
769
self .assertRaises (frozendict_error ,
769
770
exec , code , namespace )
770
771
772
+ def test_exec_globals_error_on_get (self ):
773
+ # custom `globals` or `builtins` can raise errors on item access
774
+ class setonlyerror (Exception ):
775
+ pass
776
+
777
+ class setonlydict (dict ):
778
+ def __getitem__ (self , key ):
779
+ raise setonlyerror
780
+
781
+ # globals' `__getitem__` raises
782
+ code = compile ("globalname" , "test" , "exec" )
783
+ self .assertRaises (setonlyerror ,
784
+ exec , code , setonlydict ({'globalname' : 1 }))
785
+
786
+ # builtins' `__getitem__` raises
787
+ code = compile ("superglobal" , "test" , "exec" )
788
+ self .assertRaises (setonlyerror , exec , code ,
789
+ {'__builtins__' : setonlydict ({'superglobal' : 1 })})
790
+
791
+ def test_exec_globals_dict_subclass (self ):
792
+ class customdict (dict ): # this one should not do anything fancy
793
+ pass
794
+
795
+ code = compile ("superglobal" , "test" , "exec" )
796
+ # works correctly
797
+ exec (code , {'__builtins__' : customdict ({'superglobal' : 1 })})
798
+ # custom builtins dict subclass is missing key
799
+ self .assertRaisesRegex (NameError , "name 'superglobal' is not defined" ,
800
+ exec , code , {'__builtins__' : customdict ()})
801
+
771
802
def test_exec_redirected (self ):
772
803
savestdout = sys .stdout
773
804
sys .stdout = None # Whatever that cannot flush()
0 commit comments