diff --git a/contributors/emails/anatolij.laptev.1991@gmail.com b/contributors/emails/anatolij.laptev.1991@gmail.com new file mode 100644 index 0000000000..84578ea7ae --- /dev/null +++ b/contributors/emails/anatolij.laptev.1991@gmail.com @@ -0,0 +1 @@ +anatolijlaptev1991-ctrl diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh index 68237a5fd9..635852ad9f 100755 --- a/scripts/run_tests.sh +++ b/scripts/run_tests.sh @@ -94,6 +94,21 @@ if [ -f "$HOME/.hermes/pytest_live_guard.py" ]; then fi +# ── Windows location variables (computed before we drop env) ─────────────── +# `env -i` forwards HOME, which is enough on POSIX. Native Windows CPython +# resolves Path.home() from USERPROFILE (or HOMEDRIVE+HOMEPATH), stdlib +# platform paths come from LOCALAPPDATA/APPDATA, ssl/sockets need SYSTEMROOT, +# and tempfile needs TEMP/TMP. Dropping them breaks collection on native +# Windows (issues #67385, #70813). These are location variables, not +# credentials, so forwarding them keeps the isolation intent intact. Each is +# only forwarded when actually set, so POSIX runs are byte-for-byte unchanged. +WIN_ENV=() +for _win_var in USERPROFILE HOMEDRIVE HOMEPATH LOCALAPPDATA APPDATA SYSTEMROOT TEMP TMP; do + if [ -n "${!_win_var:-}" ]; then + WIN_ENV+=("$_win_var=${!_win_var}") + fi +done + # ── Run in hermetic env ────────────────────────────────────────────────────── # env -i: start with empty environment, opt-in only what we need. # No credential var can leak — you'd have to explicitly add it here. @@ -114,10 +129,12 @@ echo "▶ launching test runner" exec env -i \ PATH="$PATH" \ HOME="$HOME" \ + ${WIN_ENV[@]+"${WIN_ENV[@]}"} \ TZ=UTC \ LANG=C.UTF-8 \ LC_ALL=C.UTF-8 \ PYTHONHASHSEED=0 \ + PYTHONUTF8=1 \ ${HERMES_RUN_SLOW_PET_TESTS:+HERMES_RUN_SLOW_PET_TESTS="$HERMES_RUN_SLOW_PET_TESTS"} \ ${HERMES_E2E_BROWSER:+HERMES_E2E_BROWSER="$HERMES_E2E_BROWSER"} \ ${EXTRA_PYTHONPATH:+PYTHONPATH="$EXTRA_PYTHONPATH"} \ diff --git a/tests/plugins/memory/test_hindsight_provider.py b/tests/plugins/memory/test_hindsight_provider.py index 62103a987c..0c72bd6203 100644 --- a/tests/plugins/memory/test_hindsight_provider.py +++ b/tests/plugins/memory/test_hindsight_provider.py @@ -10,6 +10,7 @@ import os import re import stat import sys +from pathlib import Path from types import SimpleNamespace from unittest.mock import AsyncMock, MagicMock @@ -37,8 +38,8 @@ from plugins.memory.hindsight import ( @pytest.fixture(autouse=True) -def _clean_env(monkeypatch): - """Ensure no stale env vars leak between tests.""" +def _clean_env(tmp_path, monkeypatch): + """Ensure no stale env vars or Windows home state leak between tests.""" for key in ( "HINDSIGHT_API_KEY", "HINDSIGHT_API_URL", "HINDSIGHT_BANK_ID", "HINDSIGHT_BUDGET", "HINDSIGHT_MODE", "HINDSIGHT_TIMEOUT", @@ -49,6 +50,12 @@ def _clean_env(monkeypatch): ): monkeypatch.delenv(key, raising=False) + # On Windows pathlib.Path.home() resolves USERPROFILE/HOMEDRIVE+HOMEPATH, + # not the POSIX HOME alias that these tests historically monkeypatched. + # Patch the actual API and keep all legacy profile writes in tmp_path. + isolated_home = tmp_path / "user-home" + monkeypatch.setattr(Path, "home", classmethod(lambda cls: isolated_home)) + def _make_mock_client(): """Create a mock Hindsight client with async methods."""