Skip to content

✨ feat(create): record created environments per PEP 832 - #3204

Draft
gaborbernat wants to merge 5 commits into
pypa:mainfrom
gaborbernat:832
Draft

✨ feat(create): record created environments per PEP 832#3204
gaborbernat wants to merge 5 commits into
pypa:mainfrom
gaborbernat:832

Conversation

@gaborbernat

@gaborbernat gaborbernat commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Editors and type checkers have no standard way to find a project's environments without an activated shell, so each one hard-codes a search per tool that creates environments. PEP 832 addresses that with a .python-envs file listing one environment per line, where the last line names the default environment and a .venv folder alongside counts as the implicit last line.

virtualenv creates environments, so this covers the write half. After creation it records the destination in the .python-envs file of the parent folder and moves any existing entry for it to the end, making the fresh environment the default. It leaves a destination named .venv alone, since the PEP treats it as the implicit last line. A read or write failure warns and leaves the environment usable. Pass --no-python-envs to opt out.

Rewriting the whole file loses entries when several environments land in one folder at once. Eight concurrent creations dropped between one and four of them on every attempt, so the read-modify-write runs under a .python-envs.lock file next to the recorded one. 🔒 Locking beside the resource rather than inside the app data folder holds the guarantee when the app data is read-only or disabled, and gives any other PEP 832 writer a location to agree on.

@gaborbernat
gaborbernat marked this pull request as draft August 5, 2026 00:54
@gaborbernat
gaborbernat force-pushed the 832 branch 2 times, most recently from 2f01549 to af89bd8 Compare August 5, 2026 01:09
@gaborbernat
gaborbernat force-pushed the 832 branch 2 times, most recently from 720f524 to 9611c5c Compare August 28, 2026 19:19
konstin and others added 5 commits August 28, 2026 12:20
Bind version_info once instead of repeating self.interpreter.version_info
across the python-version, version_info, and version fields.

Assert the written python-version against sys.version_info rather than the
interpreter object the code just read, so the test fails if the field value
is wrong.
The key had no home in the docs, since virtualenv documented no
`pyvenv.cfg` key anywhere. A reference page now covers the file, and a
table sets `python-version` against `version` and `version_info`, which
carry one number at three precisions and gave callers no reason to
prefer one over another.

The tutorial reads the key out of an environment it just made, the usage
guide parses it without spawning the interpreter, and the explanation of
why environments borrow from the base install says why `pyvenv.cfg`
became the place tools look.

The version assertion compared against the running interpreter while the
code reads the target one, so it passed for the wrong reason whenever
the two agree.
Editors and type checkers have no standard way to find a project's
environments without an activated shell, so each one hard-codes a search
per tool that creates environments. PEP 832 replaces that with a
.python-envs file whose last line names the default environment.

virtualenv creates environments, so it covers the write half. After
creation it records the destination in the .python-envs file of the
parent folder and moves any existing entry for it to the end, making the
fresh environment the default. A destination named .venv is left alone,
since the PEP counts it as the implicit last line. A read or write
failure warns and leaves the environment usable. Pass --no-python-envs
to opt out.

Recording rewrites the whole file, which loses entries when several
environments land in one folder at once: eight concurrent creations
dropped between one and four of them on every attempt. The
read-modify-write therefore runs under a .python-envs.lock file next to
the recorded one. Locking beside the resource rather than inside the app
data folder holds the guarantee when the app data is read-only or
disabled, and gives any other PEP 832 writer a location to agree on.

Documented across all four Diataxis dimensions, including a new
reference page cataloguing every file virtualenv writes inside and
beside an environment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants