Repository navigation
Keep hatch unit tests off the host uv path - #2067
Conversation
utils::hatch and vendor::pypi_hatch read HATCH_ENV_TYPE_VIRTUAL_UV_PATH from the process: a non-empty value switches every Hatch env to uv, so the vendored-wheel and [tool.uv.sources] refusals fire with no file setting. A developer who points Hatch at uv that way sees 18 socket-patch-core unit tests fail on a clean origin/main checkout (`cargo test -p socket-patch-core --lib`); CI passes only because no job sets the var. Both reads now go through hatch::uv_path_override(). Production builds read the process env as before; unit-test builds read only a value a test holds with an EnvGuard (test_env::guarded_var), as go_env does since #2057. A new test holds the var to cover the uv branch that the unit tests never reached before, and checks a host value stays hidden. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011f9aeR2MHrmJ9Fh9wmm3X1
|
bugbot run Generated by Claude Code |
PR SummaryLow Risk Overview Production builds behave the same as before: a non-empty path still forces the uv path. Under Reviewed by Cursor Bugbot for commit c76ed80. Configure here. |
|
Ready for review (burn-down agent).
Generated by Claude Code |
The first version of uv_path_env_counts_only_when_a_guard_holds_it held HATCH_ENV_TYPE_VIRTUAL_UV_PATH with an EnvGuard. Other utils::hatch tests are not #[serial], so while the guard was live they saw uv switched on: uv_sources_refuse_project_rewrites_under_the_uv_installer failed 2-3 times in 100 loops of `utils::hatch` on a clean env. Even an empty-value guard leaked, because EnvGuard's drop restores the previous value before it releases the key. The test now only checks that an unguarded host value stays hidden; the uv branch itself is covered by the direct uv_source_names(.., true) asserts. utils::hatch now passes 300/300 loops clean and 100/100 with the host var set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011f9aeR2MHrmJ9Fh9wmm3X1
|
bugbot run New head c76ed80 replaces 52db0e1: the first version of the new test held the uv var in an Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c76ed80. Configure here.
Final review briefWhat it does. Test-only change. Both reads of Risk: low. The non-test path is Look here
Verified
Changes I made. None. Open questions. None. (Nit, not blocking: the new test restores the var by hand, so a failed assert would leave it set for the rest of the run; harmless because every read is seamed.) Auto-merge is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
Problem
CI was healthy this run: the merge queue is empty (no queued or in-progress runs), every merge_group run since 11-12 18:56 UTC passed, main's latest push run (43324491043) and today's nightly (43373720347) are green, and no run since 11-10 needed a re-run. The 11-12 nightly Windows failure (
scan_hosted_paths_run_once_per_project_directory) was fixed by #2061. So this run takes a priority-4 robustness target from #1919, the same class as #2054–#2057 and #2063–#2066: core unit tests that pass only because CI's env is clean.A hostile-env probe of
cargo test --workspace --libonorigin/main(de81f1b) with ~20 vars the code reads set (MAVEN_REPO_LOCAL,DENO_DIR,PIPX_HOME,XDG_DATA_HOME,UV_EXCLUDE_NEWER,NUGET_PACKAGES,VIRTUAL_ENV,SSL_CERT_FILE,CI, everySOCKET_*config var, ...) found one remaining leak outside the open PRs' scope:HATCH_ENV_TYPE_VIRTUAL_UV_PATH=<any path>Failing tests on main: 16 in
vendor::pypi_hatch/vendor::pypi(hatch flavors, outage idempotence) andutils::hatch::tests::uv_sources_refuse_project_rewrites_under_the_uv_installer.Root cause
HATCH_ENV_TYPE_VIRTUAL_UV_PATHis Hatch's documented switch to the uv installer.utils/hatch.rs(run_round) andvendor/pypi_hatch.rs(require_pip_installer) read it straight from the process, so a developer who sets it gets the uv refusals on every pip-installer fixture.Fix
Both reads go through a new
hatch::uv_path_override(). Non-test builds readstd::env::varexactly as before (the CLI integration tests, e.g.mode_migration_pypi'sUV_PATHcase, link the non-test core and are unaffected). Undercfg(test)it reads only a value a liveEnvGuardholds (test_env::guarded_var), the same seam asutils::go_env::process_env(#2057).New test
uv_path_env_hides_the_host_value(#[serial]) sets the var directly (no guard) and checksuv_path_override()stays false and a uv-sourced pyproject still rewrites. It deliberately never holds the key with anEnvGuard: the otherutils::hatchtests aren't#[serial], and the first version of this test (which held a non-empty, then an empty, guarded value) madeuv_sources_refuse_project_rewrites_under_the_uv_installerfail 2–3 times per 100 loops — even the empty guard leaked, becauseEnvGuard's drop restores the previous value before releasing the key. The uv branch itself stays covered by the directuv_source_names(.., true)asserts. Fixed in the second commit.Proof
socket-patch-core --libsuite).utils::hatchlooped 300/300 on a clean env and 100/100 withHATCH_ENV_TYPE_VIRTUAL_UV_PATH=/host/uv.cargo clippy --locked -p socket-patch-core --all-features -- -D warnings(CI's invocation) is clean; rustfmt on the two touched files only.--all-targetsshows only pre-existing lints in files this PR doesn't touch.https://claude.ai/code/session_011f9aeR2MHrmJ9Fh9wmm3X1
Generated by Claude Code