From 48e25ae46eb73ac57a93eb195811fcfcf300baed Mon Sep 17 00:00:00 2001 From: AIOSAI Date: Sun, 19 Jul 2026 00:55:07 -0700 Subject: [PATCH] =?UTF-8?q?fix(prax):=20pytest=20detection=20immune=20to?= =?UTF-8?q?=20env-clearing=20=E2=80=94=20S304=20F6/F43.=20Hooks=20tests=20?= =?UTF-8?q?patch.dict(os.environ,=20clear=3DTrue)=20stripped=20PYTEST=5FCU?= =?UTF-8?q?RRENT=5FTEST,=20so=20loggers=20minted=20in=20that=20window=20fr?= =?UTF-8?q?oze=20prod-path=20handlers=20via=20the=20setup=20cache.=20get?= =?UTF-8?q?=5Fsystem/module=5Flogs=5Fdir=20now=20also=20check=20=5Fpytest?= =?UTF-8?q?=20in=20sys.modules.=201032=20prax=20+=201154=20hooks=20tests?= =?UTF-8?q?=20green.=20Residual:=20hooks-owned=20diagnostics=20writer=20by?= =?UTF-8?q?passes=20prax=20resolution=20=E2=80=94=20handed=20to=20@hooks.?= =?UTF-8?q?=20DPLAN-0250=20Track=20A,=20dispatched=20to=20@prax?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/aipass/prax/apps/handlers/config/load.py | 10 ++++++++-- src/aipass/prax/tests/test_config.py | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/aipass/prax/apps/handlers/config/load.py b/src/aipass/prax/apps/handlers/config/load.py index 18fce093..b94509fb 100755 --- a/src/aipass/prax/apps/handlers/config/load.py +++ b/src/aipass/prax/apps/handlers/config/load.py @@ -31,6 +31,7 @@ import inspect import json import logging import os +import sys import tempfile from pathlib import Path from typing import Dict, Any, Optional @@ -60,6 +61,11 @@ def _find_repo_root() -> Path: return Path.cwd() +def _is_pytest_session() -> bool: + """Detect pytest session via sys.modules (immune to patch.dict(os.environ, clear=True)).""" + return "_pytest" in sys.modules + + # Lazy SYSTEM_LOGS_DIR — resolved on first access, not at import time. # Callers should use get_system_logs_dir() for guaranteed initialization. _system_logs_dir_cache: Path | None = None @@ -76,7 +82,7 @@ def get_system_logs_dir() -> Path: p = Path(test_log_dir) / "system" p.mkdir(parents=True, exist_ok=True) return p - if os.environ.get("PYTEST_CURRENT_TEST"): + if os.environ.get("PYTEST_CURRENT_TEST") or _is_pytest_session(): p = Path(tempfile.gettempdir()) / "aipass_test_logs" / "system" p.mkdir(parents=True, exist_ok=True) return p @@ -138,7 +144,7 @@ def get_module_logs_dir(module_name: Optional[str] = None) -> Path: p = Path(test_log_dir) / module_name p.mkdir(parents=True, exist_ok=True) return p - if os.environ.get("PYTEST_CURRENT_TEST"): + if os.environ.get("PYTEST_CURRENT_TEST") or _is_pytest_session(): p = Path(tempfile.gettempdir()) / "aipass_test_logs" / module_name p.mkdir(parents=True, exist_ok=True) return p diff --git a/src/aipass/prax/tests/test_config.py b/src/aipass/prax/tests/test_config.py index a56975c4..d19ed032 100644 --- a/src/aipass/prax/tests/test_config.py +++ b/src/aipass/prax/tests/test_config.py @@ -50,6 +50,8 @@ def _fresh_import_load(monkeypatch, tmp_path): # Clear test log redirects so tests exercise real path resolution monkeypatch.delenv("AIPASS_TEST_LOG_DIR", raising=False) monkeypatch.delenv("PYTEST_CURRENT_TEST", raising=False) + # Suppress sys.modules-based pytest detection so tests can verify prod paths + monkeypatch.setattr(load_mod, "_is_pytest_session", lambda: False) return load_mod