Conversation
`Path.home()` on Windows reads `USERPROFILE` first (then
`HOMEDRIVE`+`HOMEPATH`), so `monkeypatch.setenv("HOME", str(tmp_path))`
is silently ignored and tests read/write the real runner home. This
manifests as `~/.claude/projects` auto-discovery returning the runner's
real home contents (see #644) and `~/.memtomem/config.json` writes
landing outside `tmp_path`.
Introduce a small `set_home(monkeypatch, path)` helper in
`tests/helpers.py` that sets both `HOME` and `USERPROFILE` (harmless
no-op on POSIX, correct on Windows). Apply to the 7 auto-discovery
callsites that exercise `Path.home()` indirectly:
- `test_config_overrides.py::test_detect_provider_dirs_excludes_gemini`
- `test_config_overrides.py::test_detect_provider_dirs_filters_empty_claude_memory`
- `test_config_overrides.py::test_detect_provider_dirs_finds_claude_plans_and_codex`
- `test_init_cmd.py::TestProviderDirsStep::test_write_merges_provider_dirs_into_memory_dirs`
- `test_init_cmd.py::TestIncludeProviderFlag::test_flag_resolves_categories_to_dirs`
- `test_init_cmd.py::TestIncludeProviderFlag::test_flag_silently_skips_unavailable_categories`
- `test_init_cmd.py::TestIncludeProviderFlag::test_no_flag_writes_no_provider_dirs`
Of the 7, 4 currently fail on the informational Windows job
(filters_empty_claude_memory, finds_claude_plans_and_codex, and the 3
`TestIncludeProviderFlag` tests). The other 3 are migrated for
correctness — `excludes_gemini` was a false-positive pass (assertion
held trivially when `_detect_provider_dirs()` returned empty due to
USERPROFILE redirect), and `write_merges_provider_dirs` had a HOME
monkeypatch that was inert but uses the same auto-discovery shape.
Test-only change. The 130+ other `monkeypatch.setenv("HOME", ...)`
sites across 18 test files (notably 91 in `test_init_cmd.py` and 25 in
`test_web_routes.py`) will be migrated in follow-up PRs to keep this
change axis single (one PR, one change).
Refs #644. Part of the Windows CI green journey (PR 1 #711, PR 2 #713).
Co-Authored-By: Claude <[email protected]>
…me docstring Per PR #714 review, surface the 5 manual "set both" call sites that predate this helper so the next contributor sweeping the residual ~130 ``monkeypatch.setenv("HOME", ...)`` sites doesn't re-introduce the manual pattern. Refs #644. Co-Authored-By: Claude <[email protected]>
…t_home helper Mechanical migration of all remaining HOME-only monkeypatch sites in packages/memtomem/tests/ to the set_home helper introduced in 9825210. On Windows, Path.home() reads USERPROFILE first; bare HOME setenv was silently ignored, leaking real user-home reads in fresh runners. Sweep covers: - 88 sites in test_init_cmd.py (HOME-only) - 25 sites in test_web_routes.py (24 HOME-only + 1 manual HOME+USERPROFILE pair) - 4 sites across test_web_routes_extended.py (2 manual pairs) - 4 sites across test_context_settings.py (2 manual pairs) - Manual HOME+USERPROFILE pairs in test_context_agents.py and test_server_tools_context_settings_gate.py collapsed into one set_home call - Single-site replacements in 11 other test files Manual pairs (HOME setenv followed by USERPROFILE setenv with the same value) are collapsed into a single set_home(monkeypatch, path) call, removing the redundancy that motivated the helper. Helper docstring is trimmed: the manual call-site list is no longer needed now that the sweep is complete. No production code changes. ruff check + format clean. Full impacted test set (856 tests across the 17 files) passes locally on macOS. Co-Authored-By: Claude <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Path.home()on Windows readsUSERPROFILEfirst (thenHOMEDRIVE+HOMEPATH), somonkeypatch.setenv("HOME", str(tmp_path))is silently ignored on the runner and tests end up touching the realC:\Users\runneradmin\instead oftmp_path. Per #644 this was the largest single class of Windows CI failures.This PR introduces a small
set_home(monkeypatch, path)helper intests/helpers.pythat sets bothHOMEandUSERPROFILE(no-op on POSIX, correct on Windows), then sweeps all ~133 HOME monkeypatch sites inpackages/memtomem/tests/to use it. ManualHOME+USERPROFILEpairs that already existed in 5 files (test_context_settings.py,test_web_routes_extended.py,test_web_routes.py,test_context_agents.py,test_server_tools_context_settings_gate.py) are collapsed into singleset_home(...)calls — exactly the redundancy that motivated centralizing the helper.Mechanical, test-only change. No production code touched.
ruff check+ruff format --checkclean.What's covered
test_init_cmd.pytest_web_routes.py(24 HOME-only + 1 manual pair)test_web_routes_extended.py(2 manual pairs collapsed)test_context_settings.py(2 manual pairs collapsed)test_context_agents.pyandtest_server_tools_context_settings_gate.pycollapsedtest_cli_index_noop_e2e.py,test_fastembed_cache.py,test_indexing_engine.py,test_lazy_init_acceptance.py,test_runtime_paths.py,test_uninstall_cmd.py,test_web_exclude_guard.py,test_web_hot_reload.py,test_web_routes_context_locks.py,test_web_routes_context_mutators.py,test_web_routes_context_projects.py)18 files modified, +149 / -149 (1:1 mechanical substitutions). The full sweep makes the helper the only HOME-redirection pattern in the test suite — no two-pattern drift to manage.
Cross-check (BLOCKING per plan)
Source:
gh run view 25245215735 --log-failed --job=74028225027(latest main run after PR #711 / #713 merged, 2026-05-02).Originally-targeted "auto-discovery" tests:
test_config_overrides.py::test_detect_provider_dirs_excludes_geminitest_config_overrides.py::test_detect_provider_dirs_filters_empty_claude_memory_bucket()callscategorize_memory_dir()whose forward-slash regex (#316) classifies the backslash path as"user"so the claude-memory bucket stays emptytest_config_overrides.py::test_detect_provider_dirs_finds_claude_plans_and_codextest_init_cmd.py::TestProviderDirsStep::test_write_merges_provider_dirs_into_memory_dirstest_init_cmd.py::TestIncludeProviderFlag::test_flag_resolves_categories_to_dirstest_init_cmd.py::TestIncludeProviderFlag::test_flag_silently_skips_unavailable_categoriestest_init_cmd.py::TestIncludeProviderFlag::test_no_flag_writes_no_provider_dirsThe 2 still-failing tests need both this PR (USERPROFILE redirect so
_detect_provider_dirslooks attmp_pathinstead of the runner home) and the #316 production fix (socategorize_memory_diraccepts backslash paths). After #316 lands, these 2 tests should immediately go green on Windows with no further test changes — the migration this PR ships is necessary, just not sufficient on its own.The full sweep brings ~30 additional HOME-related Windows failures into scope (notably the
test_init_cmd.pyandtest_web_routes.pyclusters from #644's symptom report).Windows CI impact
macOS, Ubuntu, lint, typecheck, golden-path, notebooks all green on the sweep run — negative pin held, no POSIX regression. Helper is a no-op on POSIX (stdlib
Path.home()ignoresUSERPROFILE).Out of scope (explicit follow-ups)
categorize_memory_dir's forward-slash regex (Windows: wizard fails to auto-detect Claude/Codex memory dirs (backslash path regex) #316). Production change, separate concern. Closes the 2 still-failingtest_detect_provider_dirs_*cases..github/workflows/ci.ymlWindows job fromcontinue-on-error: true→falseonce Windows fails are deterministic-skip-only.#644can close on this PR's merge — the helper sweep delivers its full scope (HOME redirect across the whole suite). The 2 lingering_detect_provider_dirs_*tests stay open under #316.Test plan
uv run pytest packages/memtomem/tests/ -m "not ollama" -q— full suite green locally on macOS (3951 passed)uv run ruff check packages/memtomem/tests+ruff format --check packages/memtomem/tests— clean across all 158 filescli/agent_cmd.pyandstorage/mixins/schedules.pyare unrelated)🤖 Generated with Claude Code