PYTHON-5956 Export UV_PYTHON as a version instead of an interpreter path - #126
Conversation
An absolute interpreter path outranks a virtual environment the job activates later, so `uv pip install` targeted the setup-python interpreter instead of the venv. mongo-python-driver's minimum-dependency job created a venv, activated it, installed into the interpreter behind it, and passed. A version request still overrides pyproject.toml and .python-version, and still beats a later setup-python on PATH, but a matching activated venv now wins. UV_PYTHON_PREFERENCE keeps the promise that uv never downloads an interpreter.
There was a problem hiding this comment.
🔵 Needs a closer look
It changes cross-repository CI behavior via environment-variable semantics in a shared setup action, warranting a final human verification of downstream compatibility.
Pull request overview
Updates the python/setup composite action so uv is configured using a Python version request (instead of an absolute interpreter path), allowing a subsequently activated virtual environment to take precedence while still keeping Python selection pinned to the requested version.
Changes:
- Export
UV_PYTHONas${{ inputs.python-version }}(version request) rather thanactions/setup-python’spython-path(absolute path). - Export
UV_PYTHON_PREFERENCE=only-systemso uv won’t download its own interpreter whensetup-pythonalready provided one. - Update
python/README.mdto document the new behavior and rationale.
File summaries
| File | Description |
|---|---|
| python/setup/action.yml | Switch uv configuration from interpreter path to version request and set UV_PYTHON_PREFERENCE=only-system. |
| python/README.md | Document the updated UV_PYTHON/UV_PYTHON_PREFERENCE behavior and why it avoids venv precedence issues. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| echo "UV_PYTHON=$PYTHON_PATH" >> "$GITHUB_ENV" | ||
| # A version, not an interpreter path: a path also outranks a virtual | ||
| # environment the job activates later, which silently retargets `uv pip`. | ||
| echo "UV_PYTHON=$PYTHON_VERSION" >> "$GITHUB_ENV" |
There was a problem hiding this comment.
exporting the raw python-version instead of resolved path means any input uv can't parse as a version request e.g. a newline, or specs like 3.x and 3.14-dev may either corrupt GITHUB_ENV or silently fail in a later unrelated uv step. suggest we proactively reject newlines here by trimming first e.g. something like
run: | # zizmor: ignore[github-env]
# A `|` block scalar adds a trailing newline, so trim before checking.
shopt -s extglob
VERSION="${PYTHON_VERSION##+([[:space:]])}"
VERSION="${VERSION%%+([[:space:]])}"
if [[ "$VERSION" == *[[:space:]]* ]]; then
echo "::error::python-version must be a single version, got: ${PYTHON_VERSION}"
exit 1
fi
# A version, not an interpreter path: a path also outranks a virtual
# environment the job activates later, which silently retargets `uv pip`.
echo "UV_PYTHON=$VERSION" >> "$GITHUB_ENV"
# setup-python already provided the interpreter, so never download one.
echo "UV_PYTHON_PREFERENCE=only-system" >> "$GITHUB_ENV"
Writing the raw input straight to GITHUB_ENV meant a newline in python-version split into a second line there, and the runner parses GITHUB_ENV one KEY=VALUE pair per line, so that line becomes an arbitrary extra environment variable for every later step in the job. Trailing or leading whitespace is trimmed first, so a caller who writes the input as a `|` block scalar still works. What remains must be a single token.
PYTHON-5956
UV_PYTHONheld an absolute interpreter path, which outranks a virtual environment the job activates later. mongo-python-driver's minimum-dependency job created a venv, activated it, and then installed into the setup-python interpreter behind it, passing all the while. Reported by @aclark4life on mongodb/mongo-python-driver#2990.A version request lets a matching activated venv win. It still overrides
pyproject.tomland.python-version, and still beats a secondsetup-pythonthat a later action puts onPATH, which drivers-evergreen-tools does.UV_PYTHON_PREFERENCE=only-systemkeeps uv from downloading an interpreter.Validation
Ran mongo-python-driver's workflow against this branch: 13 of 14 jobs green. The minimum-dependency job now runs pytest from
.venv/bin/python3rather than the tool cache. Every matrix entry still resolves, including3.15to CPython 3.15.0rc2 andpypy-3.11to PyPy 3.11.15.The failure is a CSOT timing test on PyPy, alongside 4763 passing. That job resolved the correct interpreter, so it is independent of this change.