Skip to content

Build the venv a Python test needs instead of imitating one - #5

Merged
siegfriedpammer merged 1 commit into
mainfrom
python-tests-off-linux
Aug 31, 2026
Merged

Build the venv a Python test needs instead of imitating one#5
siegfriedpammer merged 1 commit into
mainfrom
python-tests-off-linux

Conversation

@christophwille

Copy link
Copy Markdown
Member

The first CI run across three operating systems (run 33433853550) is red on Windows (4 failures) and macOS (2), green on Linux. Nothing in the product regressed - the build succeeds everywhere - the tests were written against a POSIX machine.

Test Windows macOS
TheProjectsOwnEnvironmentIsPreferredToWhateverIsOnPath no system python3 passes
AnImportResolvesIntoAnEnvironmentThatIsNotInTheWorktree no system python3 definition null
AProjectConfigNamingItsOwnVenvDoesNotBlindTheReview no system python3 definition null
PyrightAnswersDefinitionsAndReferencesAcrossFiles IOException deleting the temp dir passes

The fake environment is not an interpreter on macOS. A pyvenv.cfg beside a symlink at /usr/bin/python3 is how a venv looks, but /usr/bin/python3 there is the Command Line Tools stub: it re-execs the real binary, so sys.executable becomes the framework path, the planted pyvenv.cfg is never seen, and the fake site-packages never reaches sys.path. Pyright logs Unable to get Python version from interpreter and resolves the import to nothing. Reproduced locally and fixed there. The layout was POSIX-only anyway - a venv on Windows keeps packages in Lib\site-packages.

SystemPython() hardcoded /usr/bin/python3, so it threw on every Windows machine whatever Python was installed - three of the four Windows failures.

The fourth was cleanup, not an assertion: Directory.Delete while pyright's node process still holds the workspace root. TempDirectory.Delete exists for exactly that and is what every other test uses.

So: one PythonVenv helper that builds a real environment with python -m venv --without-pip (a tenth of a second, no network) and asks the interpreter where its packages go. The Python to build it with comes from LanguageServers.OnPath, which already knows a bare name on Windows means PATHEXT; with no Python at all the test is ignored instead of throwing. ~60 lines of duplicated fakes go.

Tests only - no product code, no workflow change. All three runners already have a Python, so these run rather than skip everywhere.

Verified locally on macOS: red first (same failure as CI), then 261/261 green in Release. Windows is what this PR's own CI is for.

The first CI run on three operating systems found four failures, all in the
Python tests and none in what they were testing.

The environment they set up was hand-built: a pyvenv.cfg beside a symlink at
/usr/bin/python3, on the argument that a real one would take a minute and prove
the same thing. It does not. Whether Python recognises that as a virtual
environment depends on what the symlink resolves to, and on macOS
/usr/bin/python3 is the Command Line Tools stub, which re-execs the real binary
- so sys.executable is the framework's path, the pyvenv.cfg beside the symlink
is never seen, and the environment's site-packages never reaches sys.path.
Pyright was handed an interpreter that answers nothing ("Unable to get Python
version from interpreter") and resolved the import to nothing. The layout was
POSIX-only besides: a venv on Windows keeps its packages in Lib\site-packages.

`python -m venv --without-pip` is right on every platform and costs a tenth of
a second, and the interpreter reports where its own packages go, so nothing is
guessed. Finding the Python to build it with goes through LanguageServers.OnPath,
which already knows that a bare command name on Windows means PATHEXT; where
there is none, the test says so and is ignored rather than throwing "no system
python3", which is what every Windows machine got.

The fourth failure was cleanup: deleting the workspace while the server is
still letting go of it fails on Windows and fails a test whose assertions all
passed. TempDirectory.Delete exists for that and is what every other test uses.

Assisted-by: Claude:claude-opus-5:Claude Code
@siegfriedpammer
siegfriedpammer merged commit 1b30bc1 into main Aug 31, 2026
3 checks passed
@christophwille
christophwille deleted the python-tests-off-linux branch September 1, 2026 05:04
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.

2 participants