Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/development/testing-and-quality.md
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,16 @@ and a global `loopx` may resolve to a different installed source tree.
与测试依赖;能否自动下载 Python 取决于下载配置与网络。系统 `python3` 可能过旧,
全局 `loopx` 也可能指向另一个已安装版本。

Fixtures that model a child without LoopX must isolate that child from an
inherited source-checkout `PYTHONPATH`. Check imports with the same interpreter
mode and environment as the command under test: an isolated `python -I` probe
does not qualify a later ordinary child process. Scope environment cleanup to
the fixture; retain the real negative command, recovery and settlement checks.

模拟未安装 LoopX 的子进程时,fixture 必须隔离继承的源码 `PYTHONPATH`。
导入探测应使用被测命令相同的解释器模式与环境:`python -I` 探测失败不能证明
后续普通子进程也无法导入。环境清理仅限该 fixture,保留真实失败命令、恢复及结算断言。

```bash
uv sync --extra test
uv run --extra test python -m ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentation
Expand Down
5 changes: 4 additions & 1 deletion tests/test_native_steward_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -990,10 +990,13 @@ def embedded_report_python(tmp_path, monkeypatch):
import os
from types import SimpleNamespace
from loopx.capabilities.native_chat import steward_reports
# A checkout-wide source bootstrap would make this empty child import
# LoopX even though the real embedding host has not installed it.
monkeypatch.delenv("PYTHONPATH", raising=False)
folder = tmp_path / "embedded-python"
subprocess.run([sys.executable, "-m", "venv", "--without-pip", str(folder)], check=True)
python = folder / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
missing = subprocess.run([str(python), "-I", "-c", "import loopx"],
missing = subprocess.run([str(python), "-c", "import loopx"],
cwd=tmp_path, capture_output=True, text=True)
assert missing.returncode != 0 and "ModuleNotFoundError" in missing.stderr
monkeypatch.setattr(steward_reports, "sys", SimpleNamespace(executable=str(python)))
Expand Down
Loading