Skip to content

fix: harden read-only Python test snapshot against real checkouts (#167) - #201

Merged
AntoineToussaint merged 2 commits into
mainfrom
fix/python-default-test-snapshot-robust-167
Aug 9, 2026
Merged

fix: harden read-only Python test snapshot against real checkouts (#167)#201
AntoineToussaint merged 2 commits into
mainfrom
fix/python-default-test-snapshot-robust-167

Conversation

@AntoineToussaint

Copy link
Copy Markdown
Contributor

Closes #167.

Summary

  • The default Python test adapter already runs against an ephemeral source snapshot so packaging backends can't write *.egg-info (or any build/test artifact) into the user's checkout. That snapshot used os.CopyFS, which has two failure modes on real service checkouts: it aborts the entire copy on the first irregular file (a stray unix socket / FIFO — e.g. a live-dev server left one behind), and it duplicates regenerable .git/.venv/cache trees every run, leaking stale lock/venv state into a run uv is meant to materialize fresh.
  • Replace os.CopyFS with a walk-based snapshot that skips irregular files instead of failing the whole run, and excludes .git/.hg/.svn, virtualenvs, tool caches, node_modules, and prior *.egg-info. Requirements, dependency groups, extras, interpreter pins, and the project package still resolve through the real uv adapter; the checkout stays byte-for-byte untouched.

Test plan

  • go test ./runners/python -run 'TestSnapshotSourceTree|TestRunPythonTestsStructured' -count=1 -v — new TestSnapshotSourceTree (excludes VCS/venv/cache/egg-info/irregular files, preserves symlinks) and new real-uv TestRunPythonTestsStructuredToleratesIrregularFilesInCheckout (a FIFO in the checkout no longer aborts the run; source stays clean)
  • existing real-uv regressions TestRunPythonTestsStructuredMaterializesDeclared{Requirements,DependencyGroups} still pass
  • go test ./runners/... -count=1
  • go test -race ./runners/python -count=1
  • go build ./... and go vet ./runners/python

🤖 Generated with Claude Code

AntoineToussaint and others added 2 commits August 9, 2026 06:47
)

The default Python test adapter snapshots the source into an ephemeral
tree so packaging backends never write *.egg-info (or any build artifact)
into the user's checkout. It used os.CopyFS, which aborts the entire copy
on the first irregular file (a stray unix socket / FIFO) and duplicates
regenerable VCS/venv/cache trees on every run — dragging stale lock and
venv state into a run uv is meant to materialize fresh.

Replace it with a walk-based snapshot that skips irregular files instead
of failing, and excludes .git/.venv/caches/prior *.egg-info so the source
package and its declared dependencies still resolve through the real uv
adapter while the checkout stays untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…#167)

Review of the snapshot copy surfaced two regressions vs the os.CopyFS it
replaced, plus a stale comment:

- A symlinked source root produced a dangling symlink instead of a copy,
  so the whole run executed in a non-existent directory. os.DirFS/os.CopyFS
  follow the root; filepath.WalkDir does not. Resolve the root with
  EvalSymlinks before walking (symlinks inside the tree stay verbatim).
- Excluding .git broke build backends that derive a dynamic version from
  git (setuptools_scm), which env-errored a run that should pass. VCS dirs
  are build input, not stale state — drop them from the skip set.
- The skip-set comment claimed lockfile exclusion that never happened;
  reword it to match what is actually skipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@AntoineToussaint
AntoineToussaint merged commit 6b6e714 into main Aug 9, 2026
1 check passed
@AntoineToussaint
AntoineToussaint deleted the fix/python-default-test-snapshot-robust-167 branch August 9, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python default test runner pollutes source with generated egg-info metadata

1 participant