Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 832 – Virtual environment discovery

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

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 .gitignore which ignores .venv
  • GitLab has a default .gitignore which ignores .venv
  • Codeberg has a default .gitignore which 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
    1. PDM (Frost Ming)
    2. Poetry (Randy Döring)
    3. venv (Vinay Sajip)
    4. Virtualenv (Bernát Gábor)
    5. Tox (Bernát Gábor)
    6. PyCharm (Mark Smith)
    7. library-skills (Sebastián Ramírez)
    8. uv (Tomasz Kramkowski)
  • Opposes
    1. 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:

  1. There doesn’t seem to be a clear consensus on an alternative
  2. A different name doesn’t fundamentally change any semantics
  3. Existing tools seem to already support .venv
  4. One can still use a different name for an environment thanks to .venv redirect 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 .venv redirect files from .python-envs files
  • 10-Aug-2026
    • Clarify that relative paths in .python-envs are 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
  • 31-Jul-2026
    • Changed from .venv redirect files to .python-envs
    • Dropped all proposed changes to venv
  • 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