@@ -1356,6 +1356,78 @@ def {funcname}():
13561356 with self .assertRaises (interpreters .NotShareableError ):
13571357 interp .call (defs .spam_returns_arg , arg )
13581358
1359+ def test_globals_from_builtins (self ):
1360+ # The builtins exec(), eval(), globals(), locals(), vars(),
1361+ # and dir() each runs relative to the target interpreter's
1362+ # __main__ module, when called directly. However,
1363+ # globals(), locals(), and vars() don't work when called
1364+ # directly so we don't check them.
1365+ from _frozen_importlib import BuiltinImporter
1366+ interp = interpreters .create ()
1367+
1368+ names = interp .call (dir )
1369+ self .assertEqual (names , [
1370+ '__builtins__' ,
1371+ '__doc__' ,
1372+ '__loader__' ,
1373+ '__name__' ,
1374+ '__package__' ,
1375+ '__spec__' ,
1376+ ])
1377+
1378+ values = {name : interp .call (eval , name )
1379+ for name in names if name != '__builtins__' }
1380+ self .assertEqual (values , {
1381+ '__name__' : '__main__' ,
1382+ '__doc__' : None ,
1383+ '__spec__' : None , # It wasn't imported, so no module spec?
1384+ '__package__' : None ,
1385+ '__loader__' : BuiltinImporter ,
1386+ })
1387+ with self .assertRaises (ExecutionFailed ):
1388+ interp .call (eval , 'spam' ),
1389+
1390+ interp .call (exec , f'assert dir() == { names } ' )
1391+
1392+ # Update the interpreter's __main__.
1393+ interp .prepare_main (spam = 42 )
1394+ expected = names + ['spam' ]
1395+
1396+ names = interp .call (dir )
1397+ self .assertEqual (names , expected )
1398+
1399+ value = interp .call (eval , 'spam' )
1400+ self .assertEqual (value , 42 )
1401+
1402+ interp .call (exec , f'assert dir() == { expected } , dir()' )
1403+
1404+ def test_globals_from_stateless_func (self ):
1405+ # A stateless func, which doesn't depend on any globals,
1406+ # doesn't go through pickle, so it runs in __main__.
1407+ def set_global (name , value ):
1408+ globals ()[name ] = value
1409+
1410+ def get_global (name ):
1411+ return globals ().get (name )
1412+
1413+ interp = interpreters .create ()
1414+
1415+ modname = interp .call (get_global , '__name__' )
1416+ self .assertEqual (modname , '__main__' )
1417+
1418+ res = interp .call (get_global , 'spam' )
1419+ self .assertIsNone (res )
1420+
1421+ interp .exec ('spam = True' )
1422+ res = interp .call (get_global , 'spam' )
1423+ self .assertTrue (res )
1424+
1425+ interp .call (set_global , 'spam' , 42 )
1426+ res = interp .call (get_global , 'spam' )
1427+ self .assertEqual (res , 42 )
1428+
1429+ interp .exec ('assert spam == 42, repr(spam)' )
1430+
13591431 def test_raises (self ):
13601432 interp = interpreters .create ()
13611433 with self .assertRaises (ExecutionFailed ):
0 commit comments