PEP 832 – Virtual environment discovery
- Author:
- Brett Cannon <brett at python.org>
- Discussions-To:
- Discourse thread
- Status:
- Draft
- Type:
- Standards Track
- Created:
- 19-Jan-2026
- Python-Version:
- 3.15
- Post-History:
- 15-Apr-2026 23-Apr-2026 31-Jul-2026 10-Aug-2026 08-Sep-2026
Table of Contents
- Abstract
- Motivation
- Specification
- Rationale
- Example
- Project Support for this PEP
- Backwards Compatibility
- Security Implications
- How to Teach This
- Reference Implementation
- Rejected Ideas
- Use a name other than
.venv - Recording what tool manages an environment
- Using a more structured format
- Storing the locations in pyproject.toml
- Leave .venv redirect files out of the PEP
- Support a file name suffix for .venv redirect files
- Support multiple virtual environments
- Support other environment types
- Use a name other than
- Deferred Ideas
- Acknowledgements
- Change History
- Copyright
Abstract
This PEP sets out to help make the discovery of a project’s preferred virtual environment easier. By providing a default location to look for a virtual environment as already supported by most tools as well as an easy way for workflow tools to point to a virtual environment placed somewhere other than the default location, tools will have a way to find the project’s preferred virtual environment.
Motivation
Imagine you are on your Mac laptop and you double-click your desktop shortcut
to launch Emacs (feel free to substitute “Mac” and “Emacs” with your preferred
OS and editor, respectively). You open the directory for your project in Emacs.
Now, how is Emacs (or any other tool for that matter) supposed to know where
the environments for your project are if they already exist? There’s no
possible detection of an activated virtual environment via the VIRTUAL_ENV
environment variable because you didn’t launch it from a terminal. You
potentially could scan all subdirectories for a pyvenv.cfg file to find
a virtual environment, but that assumes the virtual environments are kept
locally with the project.
What are tools like code editors, which need access to the environments being used to provide functionality like auto-complete, to do when there is currently no standardized way to tell anyone where the preferred virtual environment is? Currently, tools like editors have to hard-code a search algorithm for every tool that they choose to support. As well, the tool can document any conventions they support, but that assumes you or the tool you use to manage your virtual environments follow those conventions, which, being conventions, are not written down anywhere as a standard.
And this is not a hypothetical issue. The author of this PEP was the dev manager for Python support in VS Code for 7 years and saw firsthand the struggling of users and constant feature requests for finding one’s environments for a project.
This issue is also not restricted to code editors. Other tools have a need to access a project’s environment to know what is installed. One example is type checkers which need access to the packages that are installed to appropriately gather type annotations for 3rd-party code in order to type check the user’s code.
The goal of this PEP is to provide a specification for tools which create/manage virtual environments in order to tell other tools where the preferred/active virtual environment for a project is. And in the case of a project which has multiple virtual environments, this PEP is meant to allow for specifying the default environment to use so users are not forced to make a choice of environment if they do not want to make such a decision (e.g. at first launch of their code editor).
Please note this PEP neither condones nor discourages having multiple environments for a single project; it is neutral as to whether having a single environment or multiple ones is good or bad. It also does not condone one environment type over another.
Specification
This PEP does not define what the “root of a project” means, but the assumption
is that it is the directory one would open in their code editor to work on a
project’s code. This could be the directory where the project’s
pyproject.toml lives, or potentially the top directory of a monorepo.
The virtual environment for a project MAY be a directory named .venv
(i.e., .venv/pyvenv.cfg will exist within the directory, which can be
used to detect the existence of a virtual environment) in the root of the
project. This PEP makes no judgment whether .venv is a physical or
logical path to a directory containing a virtual environment, nor whether
logical paths should be resolved to their physical equivalent before use.
Instead of a directory containing a virtual environment, the root of a project
MAY have a .venv redirect file. This file acts as a pointer to where
the (current) virtual environment to be used for the project is located. This
virtual environment may not be the only environment associated with the
project, but it is considered the preferred virtual environment to use
at the moment by other tools. The tool managing the virtual environment
SHOULD update any .venv redirect file as appropriate when the tool or
the user desire a different virtual environment to be used by default by other
tools. As well, other tools that did not initially create the .venv
redirect file SHOULD NOT overwrite it without the user somehow expressing a
desire for the change of “ownership” of the file.
Tools looking for a virtual environment SHOULD look for either a .venv
directory or a .venv redirect file. IF a tool chooses to search parent
directories, THEN the closest .venv in either form SHOULD be selected.
A .venv redirect file MUST be encoded using UTF-8 (the UTF-8 BOM MUST
NOT be used). The file MUST only contain a single line. A trailing newline of
either \n or \r\n is allowed and MUST be ignored. An empty file or one
that only contains a newline is considered invalid.
The line in the .venv redirect file MUST point to a directory
containing a virtual environment. The path MAY use POSIX path separators–
/ –regardless of what the operating system’s native path separator is.
The path MAY be relative, and if so MUST be relative to the directory
containing the .venv file.
With regard to committing a .venv redirect file to version control, it
MAY be done when the location of the virtual environment is considered static
for a project once it is set up. For instance, some projects that use tox have
a “dev” environment defined in their configuration that ends up at
.tox/dev. Setting a .venv redirect file to point to that virtual
environment and checking in the file is reasonable. The same goes for a project
that is only worked on within a container where the location of the virtual
environment is controlled and thus static on the file system. The guidance of
NOT committing your actual virtual environment to version control is unchanged
by this PEP.
IF a tool can detect that an environment is already in use (e.g. the
VIRTUAL_ENV environment variable is set), THEN tools SHOULD respect the
user’s choice and use the activated/in-use environment over the default
environment when no previous environment selection has occurred. Tools MAY
choose to override even a previous environment selection if an environment is
detected as activated/in use.
This PEP is choosing NOT to take a position on what to do if .venv is
invalid (whether it’s a directory or a file). It is up to the tool encountering
the invalid directory/file to decide how best to handle the situation. The
expectation, though, is the invalid directory/file will not simply be ignored.
Rationale
Explicitly supporting .venv is to codify what’s already a convention:
- Poetry will detect a virtual environment in such a location,
- PDM creates virtual environments there already
- uv creates environments there already
- Hatch can support a virtual environment there
- VS Code will select it automatically, while still allowing configuration
- PyCharm will use it
- GitHub
has a default
.gitignorewhich ignores.venv - GitLab
has a default
.gitignorewhich ignores.venv - Codeberg
has a default
.gitignorewhich ignores.venv
But not every person or tool wants to keep an environment in the project or
even use the .venv name. In those situations, you need some way
to tell other tools where to find the virtual environment to use. That’s the
purpose of the .venv redirect file. The file itself is hidden as it
isn’t a critical aspect of the project (environments themselves can be viewed
as implementation details). The file name was chosen to match the .venv
directory name as the purpose of a path with that name is already well known.
As well, it is already broadly ignored by projects, so it won’t lead to
projects suddenly having a new file that they may accidentally commit.
The .venv redirect file format is simple to allow for easy
manipulation. It is easy to write a line to a .venv file via the
terminal, hence not using a more involved format like JSON.
POSIX:
realpath "<path>" > .venv
PowerShell:
(Get-Item '<path>').FullName | Set-Content .venv -Encoding utf8NoBOM
Python:
python3 -c "import pathlib, sys; p=sys.argv[1]; pathlib.Path('.venv').write_text(str(pathlib.Path(p).resolve()), encoding='utf-8')" "<path>"
Allowing for the trailing newline also plays into keeping the file format easy
to write. As well, allowing for POSIX-style paths and pointing to the directory
of the virtual environment allows for a cross-platform .venv redirect
file when it is committed to version control (i.e., avoiding Windows-style
paths and having tools worry about bin/ versus Scripts/).
The file format is also simple to avoid duplicating information that the
environment already contains. For instance, it has been suggested to record a
name or ownership of the virtual environment, but e.g., virtual environments
have the prompt recorded in pyvenv.cfg, so it does not need to be
listed separately from the environment where it may become stale.
While some projects may have multiple virtual environments available, the
concept of a current or default virtual environment is a constant. And saying
other tools shouldn’t overwrite a .venv redirect file they didn’t
create unless explicitly directed by the user is to minimize surprises while
assuming most people will only use a single workflow tool that will be creating
virtual environments.
Suggesting tools respect any activated environment is so that users have a way
to override any potential project-specific default location for an environment
(e.g., a project checks in a .venv file with a relative path
while the user very much does not want that location used as they want all
environments stored in a centralized location).
By using an explicit name associated with virtual environments, .venv
in either form does not interfere with other environment types, e.g., conda
environments. It is acknowledged, though, that this PEP doesn’t explicitly help
them either.
Example
For a project with a single virtual environment at any one time, the workflow
is simple: either place the virtual environment in .venv or write out
a .venv redirect file. For instance, uv could do this to not only
continue to do its current practice of placing the virtual environment in a
.venv directory, but also allow them to place it elsewhere either
because uv’s default changes or because the user asked for the file to be
placed elsewhere.
Other examples are Tox and Nox. Both create multiple virtual environments when
running various tasks. Both tools could provide a way to point a .venv
redirect file at the virtual environment of a failed test run to make it easier
to diagnose the failure. And by using a .venv file instead of having
users use the virtual environment directly, it lets the tools keep the layout
of where they keep their virtual environments an implementation detail. As
well, both tools could have an easy way to create a default virtual environment
to use in the general case.
Project Support for this PEP
Speaking to various tool maintainers about this PEP:
Note
Any tool without a link to an expression of (no) support gave that information privately, but with permission to state publicly.
- Supports
- PDM (Frost Ming)
- Poetry (Randy Döring)
- venv (Vinay Sajip)
- Virtualenv (Bernát Gábor)
- Tox (Bernát Gábor)
- PyCharm (Mark Smith)
- library-skills (Sebastián Ramírez)
- uv (Tomasz Kramkowski)
- Opposes
- Hatch (Cary Hawkins)
Backwards Compatibility
For the virtual environment location aspect of this PEP, there is no backwards
compatibility concern as .venv is in this PEP specifically for
backwards compatibility.
As for .venv redirect files, the biggest issue is tools that are not
expecting .venv to be a file. The error message in such instances
could be rather obtuse or opaque about why things have gone wrong. But as it
won’t implicitly work regardless, it doesn’t lead to silent errors either.
Security Implications
If tools blindly overwrite .venv, that could be a denial of service
attack if a user happened to use that directory for something else. The
expectation, though, is that would occur very rarely due to the convention of
.venv being used for virtual environments. If tools are concerned about
this issue then they can prompt the user before creating an environment at a
location that already exists.
Another concern would be using a relative path in a .venv redirect file
that is checked into version control. That could result in escaping the project
and somehow using a virtual environment elsewhere on the machine. But
that would require the user to implicitly trust the files in the repository
which is already a security risk.
Tools need to treat the contents of a .venv redirect file as path data
rather than command-line syntax. Interpolating those contents into a shell
command could allow a malicious redirect file to execute arbitrary commands.
How to Teach This
For new users, they can be told that python -m venv .venv creates a virtual
environment in .venv, and that any other tool that creates a virtual
environment on their behalf can do the same.
For experienced users, they should be taught that tools may create a virtual
environment at .venv. They should also be told there may be a
.venv redirect file instead which records the location of the virtual
environment elsewhere.
Reference Implementation
As this PEP proposes no code changes, there is no reference implementation to speak of.
Rejected Ideas
Use a name other than .venv
Some people either don’t like that .venv is hidden by some tools by
default thanks to the leading ., or don’t like venv as an
abbreviation. The relevant considerations are:
- There doesn’t seem to be a clear consensus on an alternative
- A different name doesn’t fundamentally change any semantics
- Existing tools seem to already support
.venv - One can still use a different name for an environment thanks to
.venvredirect files as proposed by this PEP
There doesn’t seem to be any specific reason to not use .venv as a name.
Because the author of this PEP also prefers the name, .venv was chosen.
Discussing alternative names was viewed as bikeshedding.
Recording what tool manages an environment
It was suggested to have .venv redirect files record what tool provided
an environment. The thinking was that there was the potential for orphaned
environments that still existed but were no longer valid for the project after
the user moved away from a tool or changed a configuration that wasn’t obvious
to the user.
The decision was made, though, that this was outside of the scope of this PEP
and not worth complicating .venv redirect files for. If a tool wanted
to keep track of what environments they created, that would be up to them to do
in their own way. As for orphaned environments that continued to exist, that
would only be a concern for the default environment as the user would need to
choose any other environment.
Using a more structured format
Using a more structured data format such as JSON for .venv redirect
files was suggested. Typically it was in order to record details about the
environment directly in .venv. But since that would be redundant data
which could be gathered from the environment itself, it was deemed not a reason
to make the file format more complicated. And the simplicity of the file format
has helped to keep the goal of the file specific and not have feature creep.
Storing the locations in pyproject.toml
It was suggested to store the locations of the environment in
pyproject.toml, but that was rejected as too rigid. Typically an
environment location is either a personal choice or a tool-specific one, not a
project one. As such, specifying the location statically didn’t seem to make
enough sense to put into the PEP, especially as a project could include its own
.venv redirect file.
Leave .venv redirect files out of the PEP
Some have suggested leaving .venv redirect files out of the PEP (or not
having this PEP at all). But the need for a simple, optional way for a workflow
tool to tell other tools where a project’s preferred virtual environment lives,
including when it is outside the project and cannot be reached through a link,
seemed strong enough to keep .venv redirect files included.
Support a file name suffix for .venv redirect files
There was a suggestion to allow for multiple .venv redirect files,
differing by a file suffix. The idea was to organize what an environment was
named/for and allow for multiple virtual environments to be listed.
In the end it didn’t seem worth the complexity. Environments would have their own way to name themselves, giving some clue as to their contents. As well, the person choosing which environment to use would not necessarily need such labels. Finally, it could lead to so many files as to be annoying.
Support multiple virtual environments
This PEP was first published supporting .venv redirect files, but then
some community pushback led to switching to .python-envs files which
allowed for listing multiple virtual environments along with a designated
default environment. The thinking was that enough projects have multiple virtual
environments that listing all of them would be useful while still preserving
the concept of a default/preferred virtual environment.
Subsequent feedback from some workflow tool authors was that maintaining such a
file would be difficult. If multiple tools were contributing to the file then
there was a risk of workflow tools overwriting each other’s work, changing what
the preferred environment was unexpectedly, etc. And with .python-envs
meant to capture all available environments, restricting to just a single
workflow tool did not seem reasonable.
Support other environment types
The .python-envs proposal mentioned above was also going to allow
supporting other environment types without requiring such support. The conda
community liked the idea, but without more support it didn’t seem worth the
complexity cost. As well, what is proposed in this PEP does not inhibit conda
environment usage and there is a deferred idea that could support conda
environments.
Deferred Ideas
During the discussions for this PEP, it was suggested to be more bold and try to come up with a way to standardize how workflow tools could communicate with other tools. This would not only let workflow tools tell other tools where an environment is, but also create environments, run commands in an environment, etc. Conversations went far enough to vote on communication protocols and continue that discussion.
In the end, though, it was decided this PEP could stand on its own without such a tool-to-tool protocol which would be a massive endeavour. But the name of “workflow service protocol” – aka “WSP”, which also means “whitespace” in many parsing grammars – was at least determined and generally liked.
Acknowledgements
Thanks to everyone who participated in an earlier discussion on this topic at https://discuss.python.org/t/22922/. Thanks to Cary Hawkins of Hatch, Randy Döring of Poetry, Frost Ming of PDM, Bernát Gábor of virtualenv & tox, Vinay Sajip of venv, and Zanie Blue of uv for feedback on the initial draft of this PEP.
Change History
- 08-Sep-2026
- Switch back to
.venvredirect files from.python-envsfiles
- Switch back to
- 10-Aug-2026
- Clarify that relative paths in
.python-envsare against the directory containing the file - Say that tools SHOULD respect any activated environment if the user has not previously selected an environment to use, and allow completely overriding any previous selection
- Give a rationale for supporting multiple environments
- Provide an example
- List tox and virtualenv support
- Mention DoS concern
- Clarify that relative paths in
- 31-Jul-2026
- Changed from
.venvredirect files to.python-envs - Dropped all proposed changes to
venv
- Changed from
- 23-Apr-2026
- Add PyCharm and library-skills support
- Have redirect files read up to the first newline
- Clarify there is no opinion on having multiple virtual environments
- Explicitly use the code editor example for the motivation
- Have
venv.executable()be configurable for the virtual environment name - Clarify symlinks are not to be treated in any special way
- Move the Rationale after the Specification and simplify the latter by moving details to the former
- Loosened things involving “MAY”, “SHOULD”, and “NOT” so tools are not required to do anything beyond how they interpret a redirect file
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.