Repository navigation
feat(python): read .python-version when resolving the version - #288
Merged
Merged
Conversation
Version resolution now reads .python-version, the file pyenv, uv and actions/setup-python use to pin a project's Python version, through the same upward walk and precedence as Node.js's .node-version and .nvmrc. Within one directory .dtvem/runtimes.json still comes first. - An exact (3.12.4) or partial (3.12) version is accepted, with pyenv's optional python- prefix. A partial version resolves to the highest installed match. - pyenv allows several versions, one per line; dtvem runs one, so the first is used. - system, pyenv-virtualenv names and pointers, and uv requests that are not a plain version number (pypy, cpython@3.12) are reported as unsupported instead of falling back to the global version. Each runtime's version files now come with their own rules (versionFileRules), starting with the optional prefix a version may carry: v for Node.js, python- for Python. As in pyenv and rbenv, the first word of the first non-comment line is used, so trailing text on that line no longer makes a Node.js file unreadable. The unsupported- version message no longer says "aliases", since Python's unsupported forms are not aliases.
This was referenced Oct 22, 2026
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
dtvem now reads
.python-versionwhen resolving the Python version. It's the file pyenv, uv andactions/setup-pythonuse to pin a project's Python. A repository that pins Python for CI, or already carries the file for pyenv or uv, gets the same version on a dtvem machine without a second, dtvem-specific file.It reuses the version-file mechanism from #286 (#283).
Type of Change
Related Issues
Resolves #284
Relates to #283, #285, #287
Changes Made
.dtvem/runtimes.json, so subdirectories inherit the file. The nearest directory wins. Within one directory.dtvem/runtimes.jsoncomes first, then.python-version, and the global version stays the fallback.3.12.4) or partial (3.12) version, with pyenv's optionalpython-prefix (pyenv-version-namestrips it). A partial version resolves to the highest installed match.#comments are skipped.systemmy-venv,3.10/envs/venv)pypy,cpython@3.12)dtvem install python <version>, anddtvem currentshows the file in its Source column.pip,python3and the other Python shims follow the file too.versionFilesnow maps each runtime to aversionFileRules(its file names plus an optional version prefix:vfor Node.js,python-for Python), so feat(ruby): read .ruby-version when resolving the version #285 and feat(config): read .tool-versions when resolving versions #287 can extend it.22.12.0 # noteand22.12.0 extraboth read as22.12.0. Trailing text used to make the file an error.… asks for "lts/*": dtvem supports only version numbers (x, x.y or x.y.z), which also fitssystemand virtualenv names.dtvem current --help, and the CLAUDE.md "Version Resolution" section.Testing
Test Environment
Test Steps
./rnr check: gofmt, golangci-lint (0 issues), and all tests pass.src/internal/config/versionfile_test.go:python-prefix, comments, multi-line, CRLF.system, virtualenv names and pointers, uv implementation requests,vprefix, empty file.runtimes.jsonin the same directory and in a parent..node-version, and Python reports its unsupported.python-version.python.exeandpip.exe, and ran them against the real install from temp project directories.Test Results
python --versionPython 3.12.12(global).python-version=3.9.9Python 3.9.9# pinned+3.8, run fromsub/deepPython 3.8.9python-3.9.9Python 3.9.93.9.9+3.8.9(pyenv multi-line)Python 3.9.9.dtvem/runtimes.json=3.8.9+.python-version=3.9.9Python 3.8.9system3.10/envs/venv3.11(not installed)Set by:the file,dtvem install python 3.11, exit 1With
.python-version=3.9,pip --versionran pip from the 3.9.9 install, anddtvem current pythonshowed3.9.9with the file as its Source.uv projects
I also ran real uv projects (uv 0.9.22). uv's cache and install folders were in a temp folder, downloads were disabled, and only the shim being tested was on
PATH:3.9)uv syncfinds no 3.9: the shim only ever offers the global 3.12.12uv syncbuilds.venvon dtvem's 3.9.9 (itspyvenv.cfghomeis dtvem's 3.9.9 install)3.14)3.11)The last row was checked against uv's source. A shim that exits non-zero is a non-critical "bad interpreter": uv skips it and keeps searching, and a non-critical error still lets uv download a Python.
An activated venv and
uv runbypass dtvem's shims entirely; unchanged. In a folder with only a.venv(no pin),pythonstill runs the global version. Matching the venv's version is #289.Checklist
golangci-lint runand fixed all issues (includes gofmt, govet, and 40+ linters)go mod tidyto clean up dependencies (no dependency changes in this PR)go test ./...)Breaking Changes
None intended. As with
.nvmrcin #286, a.python-versionin any parent directory now affects the Python shims. One holdingsystemor a virtualenv name, such as a pyenv user's~/.python-version, makes them stop with an error where they used to run the global version.Additional Notes
Out of scope, as the issue lists:
pyproject.tomlrequires-python, uv's.python-versions, and.tool-versions(#287).