fix(test): evict sys.modules cache in _register_subcommands import error test #10928

Merged
HAL9000 merged 2 commits from fix/cli-main-cov3-sysmodules-cache into master 2026-04-30 19:56:55 +00:00
+27 -5
View File
@@ -31,15 +31,32 @@ def step_reset_subcommands_flag(context: Any) -> None:
@when("cmcov3 _register_subcommands is called and an import raises an error")
def step_register_subcommands_import_error(context: Any) -> None:
"""Patch a subcommand import so _register_subcommands hits its except block."""
"""Patch a subcommand import so _register_subcommands hits its except block.
Also evicts cleveragents.cli.commands and all its sub-packages from
sys.modules so the __import__ patch actually takes effect — the module is
normally cached from the eager _register_subcommands() call at import time.
"""
import sys
import builtins
mod = context.cmcov3_mod
mock_err_console = MagicMock()
original_import = builtins.__import__
# Evict cleveragents.cli.commands and all its sub-packages/modules from
# sys.modules so the __import__ patch takes effect.
module_name = "cleveragents.cli.commands"
original_modules = {
key: sys.modules[key]
for key in list(sys.modules)
if key == module_name or key.startswith(module_name + ".")
}
for key in original_modules:
del sys.modules[key]
def failing_import(name: str, *args: Any, **kwargs: Any) -> Any:
if name == "cleveragents.cli.commands":
if name == module_name:
raise ImportError("cmcov3 forced import failure")
return original_import(name, *args, **kwargs)
@@ -51,13 +68,18 @@ def step_register_subcommands_import_error(context: Any) -> None:
patcher_builtins = patch.object(builtins, "__import__", side_effect=failing_import)
patcher_builtins.start()
context.add_cleanup(patcher_builtins.stop)
# Use BaseException to also catch SystemExit which is raised by
# _register_subcommands() on import failure (SystemExit extends
# BaseException, not Exception, so except Exception would not catch it).
try:
mod._register_subcommands()
except Exception as exc:
except BaseException as exc:
context.cmcov3_error = exc
finally:
patcher_builtins.stop()
# Restore original sys.modules entries for other scenarios.
context.add_cleanup(lambda: sys.modules.update(original_modules))
context.cmcov3_err_console = mock_err_console