fix(tests): restore original module identities after vision-routing reloads (#61597)

_fresh_modules() in test_vision_routing_31179.py deleted agent.image_routing
(+siblings) from sys.modules and never restored the ORIGINAL modules — the
reloaded copies leaked. Any later same-process test holding function refs to
the original module (test_image_routing.py) then patched the reloaded copy
via mock.patch string targets, making patches invisible: order-dependent
failures (repro: 31179 file first → 2 failures; reversed → green).

Autouse fixture now snapshots the affected sys.modules entries and restores
them on teardown. Both orders + solo runs verified green.

Masked by the per-file-isolated canonical runner; bites anyone running
pytest tests/agent/ directly.
This commit is contained in:
Teknium 2026-07-29 17:28:37 -07:00
parent 483b9e3328
commit 67435c9a02

View file

@ -60,13 +60,36 @@ def _write_config(home: str, text: str) -> None:
fp.write(text)
_RELOAD_PREFIXES = ("agent.auxiliary_client", "agent.image_routing",
"tools.vision_tools", "tools.browser_tool",
"hermes_cli.config")
def _drop_reload_targets():
for mod in list(sys.modules.keys()):
if mod.startswith(_RELOAD_PREFIXES):
del sys.modules[mod]
@pytest.fixture(autouse=True)
def _module_isolation():
"""Save/restore sys.modules entries this file reloads.
Without this, reloaded copies of agent.image_routing & friends leak
into sys.modules after the test, splitting module identity for any
later test that patches ``agent.image_routing.*`` while holding
function refs from the original module (issue #61597).
"""
saved = {name: mod for name, mod in sys.modules.items()
if name.startswith(_RELOAD_PREFIXES)}
yield
_drop_reload_targets()
sys.modules.update(saved)
def _fresh_modules():
"""Drop cached hermes modules so each test reloads against current env."""
for mod in list(sys.modules.keys()):
if mod.startswith(("agent.auxiliary_client", "agent.image_routing",
"tools.vision_tools", "tools.browser_tool",
"hermes_cli.config")):
del sys.modules[mod]
_drop_reload_targets()
# ---------------------------------------------------------------------------