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