From b35836c928b29d6f0b4ec49f31d92a98c5d6b493 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Thu, 3 Sep 2026 17:45:53 -0700 Subject: [PATCH] fix(ci-fallout): repoint 3 more tests off old facade paths; packaging test tolerates sibling scratch root modules; compat lint also catches monkeypatch.setattr/patch.object on facade aliases --- scripts/check_compat_pointers.py | 9 +++++++++ tests/cron/test_stale_module_leaf_imports.py | 7 ++++--- tests/gateway/test_discord_slash_auth.py | 2 +- tests/test_packaging_py_modules.py | 7 ++++--- .../tools/test_computer_use_empty_discovery_diagnosis.py | 5 +++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/scripts/check_compat_pointers.py b/scripts/check_compat_pointers.py index 001d753141..2fa5966da3 100644 --- a/scripts/check_compat_pointers.py +++ b/scripts/check_compat_pointers.py @@ -73,6 +73,15 @@ def main() -> int: fac = aliases.get(node.value.id) if fac and node.attr in compat[fac]: hits.append(f"{rel}:{node.lineno}: {node.value.id}.{node.attr} (via {fac})") + elif isinstance(node, ast.Call): + # monkeypatch.setattr(, "", ...) / patch.object(, "") + fn = node.func + is_setattr = (isinstance(fn, ast.Attribute) and fn.attr in ("setattr", "delattr", "object")) or ( + isinstance(fn, ast.Name) and fn.id in ("setattr", "delattr", "getattr", "hasattr")) + if is_setattr and len(node.args) >= 2 and isinstance(node.args[0], ast.Name) and isinstance(node.args[1], ast.Constant) and isinstance(node.args[1].value, str): + fac = aliases.get(node.args[0].id) + if fac and node.args[1].value in compat[fac]: + hits.append(f"{rel}:{node.lineno}: setattr/patch({node.args[0].id}, \"{node.args[1].value}\") (via {fac})") elif isinstance(node, ast.Constant) and isinstance(node.value, str): m = str_pat.fullmatch(node.value.strip()) if m: diff --git a/tests/cron/test_stale_module_leaf_imports.py b/tests/cron/test_stale_module_leaf_imports.py index e9083a6468..2b58428ef2 100644 --- a/tests/cron/test_stale_module_leaf_imports.py +++ b/tests/cron/test_stale_module_leaf_imports.py @@ -58,9 +58,10 @@ def test_docker_import_ignores_stale_base_environment(monkeypatch): from tools.environments import base from tools.environments.path_utils import sanitize_task_id_for_path - # Model base.py cached before the shared sanitizer existed. A Docker module - # imported later by tool discovery must get the helper from the leaf module. - monkeypatch.delattr(base, "sanitize_task_id_for_path", raising=False) + # base.py no longer defines the sanitizer at all (it lives in the leaf module); a Docker + # module imported later by tool discovery must bind the helper from that leaf, never + # from base's namespace. + assert "sanitize_task_id_for_path" not in vars(base) previous = sys.modules.pop("tools.environments.docker", None) try: docker = importlib.import_module("tools.environments.docker") diff --git a/tests/gateway/test_discord_slash_auth.py b/tests/gateway/test_discord_slash_auth.py index 6e2fc27d45..f935bdc292 100644 --- a/tests/gateway/test_discord_slash_auth.py +++ b/tests/gateway/test_discord_slash_auth.py @@ -432,7 +432,7 @@ def _capture_skill_registration(adapter, monkeypatch, entries): # (categories_dict, uncategorized_list, hidden_count) return ({}, list(entries), 0) - import hermes_cli.commands as _hc + import hermes_cli.commands_platforms as _hc monkeypatch.setattr( _hc, "discord_skill_commands_by_category", fake_categories, ) diff --git a/tests/test_packaging_py_modules.py b/tests/test_packaging_py_modules.py index 1c3753ea4b..62dc6a0450 100644 --- a/tests/test_packaging_py_modules.py +++ b/tests/test_packaging_py_modules.py @@ -41,7 +41,7 @@ def _imported_root_names(paths) -> dict[str, set[str]]: for path in paths: try: tree = ast.parse(path.read_text(encoding="utf-8", errors="ignore")) - except SyntaxError: + except (SyntaxError, OSError): # sibling tests drop scratch root modules mid-run continue for node in ast.walk(tree): names = [] @@ -64,8 +64,9 @@ def test_pyproject_has_no_static_py_modules_list(): def test_every_root_module_imported_by_packaged_code_is_shipped(): - shipped = _root_py_modules() - paths = [REPO_ROOT / f"{n}.py" for n in shipped] + # Scratch modules other tests write at the repo root (``_test_*.py``) are not packaged. + shipped = {n for n in _root_py_modules() if not n.startswith("_test_")} + paths = [p for n in shipped if (p := REPO_ROOT / f"{n}.py").is_file()] for pkg in PACKAGES: paths.extend((REPO_ROOT / pkg).rglob("*.py")) missing = {f: sorted(n for n in names if n not in shipped) for f, names in _imported_root_names(paths).items()} diff --git a/tests/tools/test_computer_use_empty_discovery_diagnosis.py b/tests/tools/test_computer_use_empty_discovery_diagnosis.py index bcae64a081..0028b93dcf 100644 --- a/tests/tools/test_computer_use_empty_discovery_diagnosis.py +++ b/tests/tools/test_computer_use_empty_discovery_diagnosis.py @@ -11,6 +11,7 @@ from typing import Any, Dict import pytest from tools.computer_use import cua_backend as cb +from tools.computer_use import cua_backend_driver as cb_driver # ── _empty_discovery_reason ───────────────────────────────────────────── @@ -86,7 +87,7 @@ def test_cli_fallback_fails_fast_on_daemon_not_running(monkeypatch): calls["n"] += 1 return _Proc(stdout="Cua Driver daemon is not running on /x.sock.\nStart it first with: cua-driver serve") - monkeypatch.setattr(cb, "resolve_cua_driver_cmd", lambda override=None: "cua-driver") + monkeypatch.setattr(cb_driver, "resolve_cua_driver_cmd", lambda override=None: "cua-driver") import subprocess as _sp import time as _time monkeypatch.setattr(_sp, "run", _fake_run) @@ -110,7 +111,7 @@ def test_cli_fallback_still_retries_transient_empty(monkeypatch): return _Proc(stdout="") return _Proc(stdout='{"windows": []}') - monkeypatch.setattr(cb, "resolve_cua_driver_cmd", lambda override=None: "cua-driver") + monkeypatch.setattr(cb_driver, "resolve_cua_driver_cmd", lambda override=None: "cua-driver") import subprocess as _sp import time as _time monkeypatch.setattr(_sp, "run", _fake_run)