From a8f6a28f3a56098720dc0541393195472d618ac6 Mon Sep 17 00:00:00 2001 From: anti Date: Sun, 10 May 2026 07:32:43 -0400 Subject: [PATCH] fix(test): pre-import decnet.cli at collection time to prevent agent-mode stripping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit import decnet.cli as _decnet_cli at module level guarantees the app singleton is built in master mode before any test can set DECNET_MODE=agent. Without this, test_defence_in_depth_direct_call_fails_in_agent_mode triggered a fresh import of decnet.cli with DECNET_MODE=agent active, which stripped master-only commands and wrote the stripped module to sys.modules[decnet].cli — a parent-attribute corruption that no sys.modules dict restore can fix. --- tests/cli/test_mode_gating.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/cli/test_mode_gating.py b/tests/cli/test_mode_gating.py index 5800cb51..f7e28e2c 100644 --- a/tests/cli/test_mode_gating.py +++ b/tests/cli/test_mode_gating.py @@ -9,6 +9,8 @@ from pathlib import Path import pytest +import decnet.cli as _decnet_cli # noqa: F401 — pre-load in master mode at collection time + REPO = pathlib.Path(__file__).resolve().parent.parent.parent #DECNET_BIN = REPO / ".venv" / "bin" / "decnet" @@ -78,11 +80,10 @@ def test_defence_in_depth_direct_call_fails_in_agent_mode(monkeypatch): _require_master_mode('api') is the belt-and-braces guard.""" monkeypatch.setenv("DECNET_MODE", "agent") monkeypatch.setenv("DECNET_DISALLOW_MASTER", "true") - # Re-import cli so the module-level gate re-runs (harmless here; - # we're exercising the in-function guard). Use monkeypatch.delitem so - # the original cached module is restored after the test and subsequent - # tests don't see the agent-mode-stripped app singleton. - monkeypatch.delitem(sys.modules, "decnet.cli", raising=False) + # _require_master_mode reads os.environ at call time — no reimport needed. + # Reimporting decnet.cli would corrupt sys.modules["decnet"].cli (the + # parent-package attribute that `import decnet.cli as x` resolves through) + # and no restore strategy can fix that without reloading the decnet package. from decnet.cli import _require_master_mode import typer with pytest.raises(typer.Exit):