@@ -1244,6 +1244,127 @@ def test_resolve():
12441244 self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
12451245 self .assertIn ("OK" , result .stdout )
12461246
1247+ def test_load_global_respects_rebound_global_during_reification (self ):
1248+ """LOAD_GLOBAL should not overwrite a global rebound by the import hook."""
1249+ code = textwrap .dedent ("""
1250+ import builtins
1251+ import types
1252+
1253+ real_import = builtins.__import__
1254+ calls = []
1255+ sentinel = object()
1256+
1257+ lazy import target_module as target
1258+
1259+ def custom_import(name, globals=None, locals=None, fromlist=None, level=0):
1260+ if name == "target_module":
1261+ calls.append(name)
1262+ globals["target"] = sentinel
1263+ module = types.ModuleType(name)
1264+ module.VALUE = "resolved"
1265+ return module
1266+ return real_import(name, globals, locals, fromlist, level)
1267+
1268+ builtins.__import__ = custom_import
1269+ try:
1270+ def trigger_load_global():
1271+ return target
1272+
1273+ resolved = trigger_load_global()
1274+ assert resolved.VALUE == "resolved"
1275+ assert globals()["target"] is sentinel
1276+ assert calls == ["target_module"], calls
1277+ finally:
1278+ builtins.__import__ = real_import
1279+ print("OK")
1280+ """ )
1281+ result = subprocess .run (
1282+ [sys .executable , "-c" , code ],
1283+ capture_output = True ,
1284+ text = True
1285+ )
1286+ self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
1287+ self .assertIn ("OK" , result .stdout )
1288+
1289+ def test_load_name_respects_deleted_global_during_reification (self ):
1290+ """LOAD_NAME should not recreate a global deleted by the import hook."""
1291+ code = textwrap .dedent ("""
1292+ import builtins
1293+ import types
1294+
1295+ real_import = builtins.__import__
1296+ calls = []
1297+
1298+ lazy import target_module as target
1299+
1300+ def custom_import(name, globals=None, locals=None, fromlist=None, level=0):
1301+ if name == "target_module":
1302+ calls.append(name)
1303+ del globals["target"]
1304+ module = types.ModuleType(name)
1305+ module.VALUE = "resolved"
1306+ return module
1307+ return real_import(name, globals, locals, fromlist, level)
1308+
1309+ builtins.__import__ = custom_import
1310+ try:
1311+ resolved = target
1312+ assert resolved.VALUE == "resolved"
1313+ assert "target" not in globals()
1314+ assert calls == ["target_module"], calls
1315+ finally:
1316+ builtins.__import__ = real_import
1317+ print("OK")
1318+ """ )
1319+ result = subprocess .run (
1320+ [sys .executable , "-c" , code ],
1321+ capture_output = True ,
1322+ text = True
1323+ )
1324+ self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
1325+ self .assertIn ("OK" , result .stdout )
1326+
1327+ def test_module_attr_respects_rebound_global_during_reification (self ):
1328+ """Module attribute access should not overwrite a rebound lazy binding."""
1329+ code = textwrap .dedent ("""
1330+ import builtins
1331+ import types
1332+
1333+ real_import = builtins.__import__
1334+ calls = []
1335+ sentinel = object()
1336+ holder = types.ModuleType("holder")
1337+ holder.__dict__["__builtins__"] = builtins
1338+
1339+ exec("lazy import target_module as target", holder.__dict__)
1340+
1341+ def custom_import(name, globals=None, locals=None, fromlist=None, level=0):
1342+ if name == "target_module":
1343+ calls.append(name)
1344+ holder.__dict__["target"] = sentinel
1345+ module = types.ModuleType(name)
1346+ module.VALUE = "resolved"
1347+ return module
1348+ return real_import(name, globals, locals, fromlist, level)
1349+
1350+ builtins.__import__ = custom_import
1351+ try:
1352+ resolved = holder.target
1353+ assert resolved.VALUE == "resolved"
1354+ assert holder.__dict__["target"] is sentinel
1355+ assert calls == ["target_module"], calls
1356+ finally:
1357+ builtins.__import__ = real_import
1358+ print("OK")
1359+ """ )
1360+ result = subprocess .run (
1361+ [sys .executable , "-c" , code ],
1362+ capture_output = True ,
1363+ text = True
1364+ )
1365+ self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
1366+ self .assertIn ("OK" , result .stdout )
1367+
12471368 def test_add_lazy_to_globals (self ):
12481369 code = textwrap .dedent ("""
12491370 import sys
0 commit comments