From 87d45fda64ca44872fd6db60413de7303d8620fa Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 7 Jul 2026 15:41:52 -0700 Subject: [PATCH 01/18] Update the abstract --- peps/pep-0832.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 931c0dd3565..ad125b467a9 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -13,10 +13,11 @@ Post-History: `15-Apr-2026 `__ Abstract ======== -This PEP sets out to help make the discovery of a project's virtual environment -easier for tools by providing a default location as well as a way for a project -to point to its preferred virtual environment when it differs from the default -location. +This PEP sets out to help make the discovery of a project's existing +environments 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 list any other environments (virtual or not), tools will have +a way to find any and all existing environments for a project. Motivation From f908bcefe26237a8982956549a9b24b1b3938006 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 7 Jul 2026 15:42:03 -0700 Subject: [PATCH 02/18] Update the motivation --- peps/pep-0832.rst | 49 ++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index ad125b467a9..8dc10c8c4a9 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -27,41 +27,46 @@ 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 virtual environment for your project is? There's no possible detection of -an activated virtual environment via the ``VIRTUAL_ENV`` environment variable +the environments for your project are? There's no possible detection of an +activated virtual environment via the ``VIRTUAL_ENV`` environment variable as you didn't launch from a terminal. You potentially could scan all -subdirectories for a :file:`pyvenv.cfg` file to find the virtual environment, -but that assumes the virtual environment is kept locally with the project and -that there is only one of them and not several to ambiguously choose from. What -are tools like code editors which need access to the virtual environment being -used to provide functionality like auto-complete to do when there is currently -no standardized way to tell anyone where the virtual environment is? Currently, +subdirectories for a :file:`pyvenv.cfg` file to find a virtual environment, but +that assumes the virtual environments are kept locally with the project and +that there is only one of them and not several to ambiguously choose from. +As well, not all projects use virtual environments and may use a different +project isolation mechanism like conda environments. + +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 any environments are? Currently, tools like editors have to hard-code a search algorithm for every tool that they choose to support. As well, they can document any conventions they -support, but that assumes you or the tool you use to manage your virtual -environments follow those conventions. +support, but that assumes you or the tool you use to manage your environments +follow those conventions which by being a convention are not written down +anywhere. 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 -user struggles and constant feature requests involving trying to find one's -preferred/default virtual environment for a project. +user struggles 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 the virtual environment to know what is installed. One example is +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 a way to tell other tools where the -(default) virtual environment for a project is. In the case of a project which -has multiple virtual environments, this PEP is meant to allow for specifying -the default or "active" virtual environment so users are not forced to make a -choice of virtual environment to use if one does 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 virtual environments for a -single project; it is neutral as to whether having a single virtual environment -or multiple ones is good or bad. +create/manage environments a way to tell other tools where the environments for +a project are. And in the case of a project which has multiple 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 one does 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 ============= From 899bfbd325e4ed1ac47cb9cbd778ec6e38119649 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 7 Jul 2026 16:18:00 -0700 Subject: [PATCH 03/18] Update the specification --- peps/pep-0832.rst | 112 +++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 71 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 8dc10c8c4a9..f9b38c89b1f 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -80,77 +80,47 @@ The virtual environment for a project MAY be in a directory named :file:`.venv` (i.e. :file:`.venv/pyvenv.cfg` will exist which can be used to detect the existence of a virtual environment) in the root of the project. -In all other situations where placing a virtual environment at the project root -in a :file:`.venv` directory is not possible or desirable, a :file:`.venv` -**file** SHOULD be written in the project root instead. The file MUST contain -at least a single line recording the path to the directory of the -virtual environment (i.e. the directory containing :file:`pyvenv.cfg`). The -file MUST be encoded in UTF-8. If ``\r\n`` or ``\n`` are contained in the file -then the path is considered from the start of the file until the first newline -in the file with the rest of the file's contents ignored but reserved for -future use cases, otherwise the path is the entire contents of the file. There -are NO requirements on path formatting (i.e. a POSIX path is not required). The -path MAY be relative to the :file:`.venv` file. Tools SHOULD verify that the -directory the file points to exists before using it. - -Tools looking for a virtual environment SHOULD look for the :file:`.venv` -directory or file and handle them appropriately. Tools SHOULD NOT prefer one -format over another when searching for a virtual environment (e.g. if a tool -looks up through parent directories for a virtual environment, it shouldn't -look for a directory first and then a file; the first thing found with the -:file:`.venv` path name should be chosen). Sharing the same path name for both -the directory and file means there is no precedence issue within the same -directory. If the found ``.venv`` is a symlink, it does NOT alter how the -resolved file is treated; symlinks SHOULD be treated as if they were a regular -entry in the file system. - -This PEP proposes some changes to the :mod:`venv` module to go along with the -above recommendations: - -#. A ``DEFAULT_NAME: str`` global that's set to ``".venv"``. -#. Create a - ``read_redirect_file(project_root: os.PathLike|str) -> pathlib.Path[str]`` - function for getting the path from a redirect file in - ``project_root / DEFAULT_NAME``. Raises an exception if the location - recorded in the redirect file does not exist. -#. :class:`venv.EnvBuilder` gains - ``write_redirect_file(project_root: os.PathLike, env_dir: os.PathLike) -> None`` - and an equivalent ``write_redirect_file()`` function for the module. The - function and method will create a redirect file at - ``project_root / DEFAULT_NAME`` that points to *env_dir*. -#. :meth:`venv.EnvBuilder.create` and :func:`venv.create` gain a keyword-only - ``project_root: os.PathLike | None`` parameter that will write out a - :file:`.venv` file to that directory via - ``EnvBuilder.write_redirect_file()``. If the value for *env_dir* ends in - ``DEFAULT_NAME`` and *project_root* points to the parent directory of - *env_dir* then ``write_redirect_file()`` will not be called. -#. The *env_dir* parameter for :meth:`venv.EnvBuilder.create` and - :func:`venv.create` get a default value of ``DEFAULT_NAME``. -#. The ``-m venv`` CLI will gain a default value for its *ENV_DIR* argument of - ``DEFAULT_NAME`` (it's currently an error not to provide the argument). -#. The ``-m venv`` CLI will gain a ``--project-root`` option that mirrors the - new parameter to :meth:`venv.EnvBuilder.create`. It will be an error to use - the option when multiple *ENV_DIR* arguments are provided. -#. A function named - ``executable(dir: os.PathLike, name: str = DEFAULT_NAME, *, traverse: bool = False) -> pathlib.Path`` - will be added; it will look for a virtual environment in *dir* at *name* - (directory or redirect file; defaults to ``DEFAULT_NAME``) and return the - path to the ``python`` executable for the virtual environment, raising - an exception if the path to a virtual environment is not found or the - virtual environment is somehow corrupted. If *traverse* is true, then - traversal through the parent directories of *dir* to look for - ``DEFAULT_NAME`` as a file or directory will be done and will stop at the - first ``DEFAULT_NAME`` found closest to *dir*. - -With regard to committing a :file:`.venv` file to version control, it MAY be -done when the location of the virtual environment is considered static to 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 :file:`.venv` 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. +The root of a project MAY have a :file:`.python-envs` file. This file acts as a +listing of all known environments for the project (sans :file:`.venv`; how that +and :file:`.python-envs` work together will be covered later). The +:file:`.python-envs` MUST be encoded using UTF-8. Each line of the file +represents an environment that is usable by the project. A trailing newline of +either ``\n`` or ``\r\n`` is allowed and will be ignored. + +Lines in a :file:`.python-envs` file MAY be paths to an environment. Paths MAY +be relative, and if they are they are relative they MUST be relative to the +:file:`.python-envs` file. IF a path is for a virtual environment, THEN path +MUST be to the directory of the virtual environment (i.e. the directory +containing the :file:`pyvenv.cfg` file). A line MAY represent any type of an +environment. Tools reading a :file:`.python-envs` MAY choose what sort of +environments they support. There are NO other restrictions on how +environments are represented or what type of environment is in a +:file:`.python-envs` file. + +Duplicate lines MAY be in the file. Listing the same environment multiple times +does NOT carry any meaning. + +The last environment listed in a :file:`.python-envs` file MUST be considered +the default environment when a default environment is desired. IF a tool does +not support the last environment listed THEN the tool MUST either ask the user +which environment to use OR error out. + +IF both a virtual environment in a :file:`.venv` directory and a +:file:`.python-envs` file exist side-by-side, THEN the :file:`.venv` directory +MUST be implicitly considered the last line in the :file:`.python-envs` file. +This also means the :file:`.venv` virtual environment is considered the default +virtual environment. + +With regard to committing a :file:`.python-envs` file to version control, it +MAY be done when the location of the environment(s) is considered static +to 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 :file:`.python-envs` 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 +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. Rationale From fe0eb0707104a604a504bfc6ab003072c2ad1ad5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 8 Jul 2026 10:26:33 -0700 Subject: [PATCH 04/18] Clarify that unrecognized lines may be ignored --- peps/pep-0832.rst | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index f9b38c89b1f..5ef2726c0bd 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -85,7 +85,7 @@ listing of all known environments for the project (sans :file:`.venv`; how that and :file:`.python-envs` work together will be covered later). The :file:`.python-envs` MUST be encoded using UTF-8. Each line of the file represents an environment that is usable by the project. A trailing newline of -either ``\n`` or ``\r\n`` is allowed and will be ignored. +either ``\n`` or ``\r\n`` is allowed and MUST be ignored. Lines in a :file:`.python-envs` file MAY be paths to an environment. Paths MAY be relative, and if they are they are relative they MUST be relative to the @@ -93,12 +93,14 @@ be relative, and if they are they are relative they MUST be relative to the MUST be to the directory of the virtual environment (i.e. the directory containing the :file:`pyvenv.cfg` file). A line MAY represent any type of an environment. Tools reading a :file:`.python-envs` MAY choose what sort of -environments they support. There are NO other restrictions on how -environments are represented or what type of environment is in a -:file:`.python-envs` file. +environments they support and thus MAY ignore any lines they do not +understand. There are NO other restrictions on how environments are represented +or what type of environment is in a :file:`.python-envs` file. Duplicate lines MAY be in the file. Listing the same environment multiple times -does NOT carry any meaning. +does NOT carry any meaning. Any tool MAY remove duplicates at any point, but +UNLESS the last/default environment is being actively changed then that last +entry MUST be retained. The last environment listed in a :file:`.python-envs` file MUST be considered the default environment when a default environment is desired. IF a tool does @@ -126,6 +128,18 @@ by this PEP. Rationale ========= + +XXX .venv + +XXX trailing newline +XXX allowing any type of environment +XXX allowing any representation +XXX allowing duplicates +XXX why the last entry is the default +XXX why .venv is implicitly at the end of .python-envs + +XXX getting virtual environment name from the prompt + There are three aspects to where a virtual environment is placed. The first is whether the virtual environment is local to the project or stored globally with other virtual environments. Keeping the virtual environment local means that it From cfc3f998bda85ec6f8b650ec8bfcaf504380689b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 8 Jul 2026 16:15:11 -0700 Subject: [PATCH 05/18] Fill in the Rationale for `.venv` and the `.python-envs` file name --- peps/pep-0832.rst | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 5ef2726c0bd..61f0668b3a4 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -128,16 +128,42 @@ by this PEP. Rationale ========= +Explicitly supporting :file:`.venv` is to codify what's already a convention: -XXX .venv +- `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 :file:`.gitignore` which ignores :file:`.venv` +- `GitLab `__ + has a default :file:`.gitignore` which ignores :file:`.venv` +- `Codeberg `__ + has a default :file:`.gitignore` which ignores :file:`.venv` + +But not every person or tool wants to keep an environment in the project or +even use the :file:`.venv` name. But in those situations, you need _some_ way +to tell other tools where to find the environments. That's the purpose of the +:file:`.python-envs` 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 make sure it didn't clash with any other +tool using the same name while still being self-descriptive. -XXX trailing newline XXX allowing any type of environment XXX allowing any representation XXX allowing duplicates XXX why the last entry is the default XXX why .venv is implicitly at the end of .python-envs +XXX trailing newline XXX getting virtual environment name from the prompt There are three aspects to where a virtual environment is placed. The first is From aaa86909565a3232f23f254ddfd5dd759c9e03e3 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 13 Jul 2026 16:52:03 -0700 Subject: [PATCH 06/18] Update the support section --- peps/pep-0832.rst | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 61f0668b3a4..606337069e1 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -264,37 +264,7 @@ Speaking to various tool maintainers about this PEP: - 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. Hatch (Cary Hawkins) - 7. `PyCharm `__ (Mark Smith) - 8. `library-skills `__ (Sebastián Ramírez) - -- Lukewarm - - 1. uv (Zanie Blue) - -- Opposes - - 1. Hatch (Ofek Lev) - - -Backwards Compatibility -======================= - -For the virtual environment location aspect of this PEP, the backwards -compatibility concern would be over some alternative use of :file:`.venv`. But -due to the current usage already in the community, the likelihood of an -alternative usage is probably small. This will likely lead to tools showing an -error message when a ``.venv`` file is used, though. While the error message -would likely be around ``.venv`` being a file and thus not explaining *why* -there's a file, it just prevents any tool from overlooking the ``.venv`` file and -blindly creating another virtual environment. - -The other possible backwards compatibility concern is the new default value for + 1. VS Code the ``-m venv`` CLI. But since it's currently an error not to specify the directory, the impact should be minimal. From 65a3ace582d8b9b5a3beaaae70e4f25b43a25b17 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 13 Jul 2026 16:52:17 -0700 Subject: [PATCH 07/18] Update the Rationale --- peps/pep-0832.rst | 167 ++++++++++++++++++---------------------------- 1 file changed, 65 insertions(+), 102 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 606337069e1..9b497e3889c 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -76,9 +76,12 @@ is 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 :file:`pyproject.toml` lives, or potentially the top directory of a monorepo. -The virtual environment for a project MAY be in a directory named -:file:`.venv` (i.e. :file:`.venv/pyvenv.cfg` will exist which can be used to -detect the existence of a virtual environment) in the root of the project. +The virtual environment for a project MAY be a path named :file:`.venv` +(i.e. :file:`.venv/pyvenv.cfg` will exist which can be used to detect the +existence of a virtual environment) in the root of the project. This PEP makes +no judgment whether :file:`.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. The root of a project MAY have a :file:`.python-envs` file. This file acts as a listing of all known environments for the project (sans :file:`.venv`; how that @@ -89,8 +92,8 @@ either ``\n`` or ``\r\n`` is allowed and MUST be ignored. Lines in a :file:`.python-envs` file MAY be paths to an environment. Paths MAY be relative, and if they are they are relative they MUST be relative to the -:file:`.python-envs` file. IF a path is for a virtual environment, THEN path -MUST be to the directory of the virtual environment (i.e. the directory +:file:`.python-envs` file. IF a path is for a virtual environment, THEN the +path MUST be to the directory of the virtual environment (i.e. the directory containing the :file:`pyvenv.cfg` file). A line MAY represent any type of an environment. Tools reading a :file:`.python-envs` MAY choose what sort of environments they support and thus MAY ignore any lines they do not @@ -107,8 +110,8 @@ the default environment when a default environment is desired. IF a tool does not support the last environment listed THEN the tool MUST either ask the user which environment to use OR error out. -IF both a virtual environment in a :file:`.venv` directory and a -:file:`.python-envs` file exist side-by-side, THEN the :file:`.venv` directory +IF both a virtual environment in a :file:`.venv` path and a +:file:`.python-envs` file exist side-by-side, THEN the :file:`.venv` path MUST be implicitly considered the last line in the :file:`.python-envs` file. This also means the :file:`.venv` virtual environment is considered the default virtual environment. @@ -150,107 +153,52 @@ Explicitly supporting :file:`.venv` is to codify what's already a convention: has a default :file:`.gitignore` which ignores :file:`.venv` But not every person or tool wants to keep an environment in the project or -even use the :file:`.venv` name. But in those situations, you need _some_ way +even use the :file:`.venv` name. In those situations, you need _some_ way to tell other tools where to find the environments. That's the purpose of the :file:`.python-envs` 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 make sure it didn't clash with any other tool using the same name while still being self-descriptive. -XXX allowing any type of environment -XXX allowing any representation -XXX allowing duplicates -XXX why the last entry is the default -XXX why .venv is implicitly at the end of .python-envs - -XXX trailing newline -XXX getting virtual environment name from the prompt - -There are three aspects to where a virtual environment is placed. The first is -whether the virtual environment is local to the project or stored globally with -other virtual environments. Keeping the virtual environment local means that it -is isolated and unique to the project. As well, it means that if you delete the -project you also delete the virtual environment. If you store the virtual -environment globally then you can share it among multiple projects and delete -all virtual environments at once by deleting the directory that contains them -all. Keeping virtual environments global also means it won't be backed up -automatically if a project is stored e.g. in a directory automatically backed -up to remote storage where you pay based on how much storage you use. - -Another aspect is the directory name used for the virtual environment -(although this really only affects local virtual environments). If one views -virtual environments as more of an implementation detail, a directory name -starting with :file:`.` seemingly makes sense to mark it hidden or de-emphasized -in various tools such as shells and code editors. But hiding it can make -accessing the directory harder via tools that don't expose paths starting with -a ``.``. - -Lastly, there's whether you have one virtual environment at a time or many. -Having only one can minimize disk space for some tools and keeps it simple by -not trying to manage multiple virtual environments. Having multiple virtual -environments, though, means not having to constantly recreate virtual -environments when e.g. needing to test against multiple Python versions. - -This PEP takes a two-pronged approach to making virtual environments easily -discoverable while supporting all aspects mentioned above. First, this PEP -suggests putting the virtual environment in the :file:`.venv` -directory of the project (this can be a hardlink, symlink, etc.). This name -has been chosen due to preexisting tool support: - -- `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 :file:`.gitignore` which ignores :file:`.venv` -- `GitLab `__ - has a default :file:`.gitignore` which ignores :file:`.venv` -- `Codeberg `__ - has a default :file:`.gitignore` which ignores :file:`.venv` - -But for various reasons (from personal preference to preexisting tool defaults), -the :file:`.venv` directory in the project root may not work. In those cases, a -:file:`.venv` **file** which points to the virtual environment by default -should be provided in the project's root directory (i.e. the same location as -specified above for the :file:`.venv` directory). This file should point to the -virtual environment to use by default; there can be other virtual environments -for the project, but the :file:`.venv` file should point to the virtual -environment to be used if no preference is specified. While a symlink for -:file:`.venv` could serve the same purpose, not all file systems support -symlinks. As well, situations like automatic backup of a directory to a cloud -backup solution require a level of indirection so that backup tools don't -implicitly follow into a virtual environment and back it up. - -The :file:`.venv` file is meant to represent the virtual environment a workflow -tool is expected to use that is external to the one that wrote the -:file:`.venv` file (e.g. Hatch wrote the file and VS Code is going to read it). -This means that a workflow tool shouldn't update the :file:`.venv` file when -running a test suite through multiple versions of Python. But if the workflow -tool has a command to control what virtual environment is used when running -Python, then the file should be updated as necessary to match what environment -the workflow tool would use (e.g. :file:`.venv` should always match what -virtual environment `'hatch run' `__ -would use). This is not expected to cause a "noisy neighbour" problem as it's -not expected to change that rapidly. - -The format for the :file:`.venv` redirect file is for ease of use. Allowing -newlines in the file makes it easy to create or edit the file in a code editor -that automatically adds newlines to the end of a file. Only reading up to the -first newline, if one exists, also allows for adding more data to the file in -the future. It also allows for easy shell scripting to read the file, e.g. -``head -n 1 .venv | tr -d '\n'`` or ``Get-Content .venv -TotalCount 1``. - -Having tools check for the existence of the path before using it is to prevent -tools from being tricked into e.g. blindly passing the file contents into -``subprocess.run(..., shell=True)``. +The :file:`.python-envs` file is specifically agnostic when it comes to what +type of environment can be represented. This helps future-proof the file for +unforseen, future environments. As well, leaving the representation as loose as +being what a single line of a file can represent helps with that +representation (which can include alternative representations for virtual +environments, e.g. connecting over SSH). It does mean, though, that tools +SHOULD check the line for appropriate use (e.g. make sure the environment +location is legitimate before passing it to ``subprocess.run()``). + +The file format is simple to allow for easy manipulation. Having a +line-delimited file format makes it easy to append a line to a +:file:`.python-envs` file via the terminal, e.g.: + +- ``echo "" >> .python-envs`` +- ``Add-Content .python-envs ""`` +- ``python3 -c "import sys; p=sys.argv[1]; open('.python-envs', 'a').write(p)" ""`` + +To make appending as simple as a process as possible, duplicate lines are +allowed to occur in :file:`.python-envs`. This alleviates having to check the +file before appending. This is also why a trailing newline is allowed in the +file. + +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 for environments, but e.g. virtual environments have the prompt recorded +in :file:`pyvenv.cfg`, to it doesn't need to be listed separate from the +environment where it may become stale. + +This is also why the last line is the default environment: the expectation is +people will be adding the environment they want to use and not simply recording +an available environment. This all tries to make what is expected to be the +most common action be the easiest action. + +Having :file:`.venv` represent the last, and thus default, environment in a +:file:`.python-envs` file is for practical reasons. Tools that predate this +PEP may use the :file:`.venv` location, and so this is a +backwards-compatibility consideration. And if a user is using such a tool that +uses :file:`.venv` then they likely already considered that virtual environment +the default. Project Support for this PEP @@ -265,6 +213,21 @@ Speaking to various tool maintainers about this PEP: - Supports 1. VS Code + + +Backwards Compatibility +======================= + +For the virtual environment location aspect of this PEP, the backwards +compatibility concern would be over some alternative use of :file:`.venv`. But +due to the current usage already in the community, the likelihood of an +alternative usage is probably small. This will likely lead to tools showing an +error message when a ``.venv`` file is used, though. While the error message +would likely be around ``.venv`` being a file and thus not explaining *why* +there's a file, it just prevents any tool from overlooking the ``.venv`` file and +blindly creating another virtual environment. + +The other possible backwards compatibility concern is the new default value for the ``-m venv`` CLI. But since it's currently an error not to specify the directory, the impact should be minimal. From 5e2d0c60bc2d41093f955fed984d96fab8714347 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 14 Jul 2026 15:54:09 -0700 Subject: [PATCH 08/18] Update Backwards Compatibility --- peps/pep-0832.rst | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 9b497e3889c..7597bfa8b54 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -218,18 +218,14 @@ Speaking to various tool maintainers about this PEP: Backwards Compatibility ======================= -For the virtual environment location aspect of this PEP, the backwards -compatibility concern would be over some alternative use of :file:`.venv`. But -due to the current usage already in the community, the likelihood of an -alternative usage is probably small. This will likely lead to tools showing an -error message when a ``.venv`` file is used, though. While the error message -would likely be around ``.venv`` being a file and thus not explaining *why* -there's a file, it just prevents any tool from overlooking the ``.venv`` file and -blindly creating another virtual environment. - -The other possible backwards compatibility concern is the new default value for -the ``-m venv`` CLI. But since it's currently an error not to specify the -directory, the impact should be minimal. +For the virtual environment location aspect of this PEP, there is no backwards +compatibility concern as :file:`.venv` is in this PEP specifically for +backwards compatibility. + +As for :file:`.python-envs`, that file name is not known to be in use. The +biggest backwards compatibility concern is a tool producing it and it not +being used as expected. After that is the file not being ignored by version +control upfront. Security Implications From c5f52ee8f1d5c6aa5542a19b642e1ec87f126a11 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 14 Jul 2026 15:54:25 -0700 Subject: [PATCH 09/18] Update Security Implications --- peps/pep-0832.rst | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 7597bfa8b54..3f9cb218f61 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -231,15 +231,9 @@ control upfront. Security Implications ===================== -Not checking the contents of a potentially malicious :file:`.venv` file and -passing it to a shell process (e.g. ``subprocess.run(..., shell=True)``) would -be a serious security concern. This is why this PEP says tools MUST make sure -the path is valid before using it. - -Setting a :file:`.venv` file to a path that isn't a virtual environment is only -a concern if the arguments the user provided to the executable were also a -concern. That would require the user to craft appropriate arguments -on top of using the malicious :file:`.venv` file. +Not checking the contents of a potentially malicious :file:`.python-envs` file +and passing it to a shell process (e.g. ``subprocess.run(..., shell=True)``) +would be a serious security concern. How to Teach This From ac2621891a49f306a50754ac2df8318dff68b9c4 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 14 Jul 2026 15:54:46 -0700 Subject: [PATCH 10/18] Update How to Teach This --- peps/pep-0832.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 3f9cb218f61..2db4d17fccf 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -239,14 +239,17 @@ would be a serious security concern. How to Teach This ================= -For new users, they can be told that ``python -m venv`` creates a virtual +For new users, they can be told that ``python -m venv .venv`` creates a virtual environment in :file:`.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 the default location for a -project's virtual environment is at the root of the project in :file:`.venv`. -If the currently active virtual environment lives elsewhere, a :file:`.venv` -file will be there to tell them where to find the virtual environment. +For experienced users, they should be taught that tools may create a virtual +environment at :file:`.venv`. They should also be told there may be a +:file:`.python-envs` file which records the location of other environments with +the last environment listed considered the default. As well, they should be +taught that if both :file:`.venv` and :file:`.python-envs` exist in the same +directory then :file:`.venv` is implicitly the last, and thus default, +environment in :file:`.python-envs`. Reference Implementation From d30983937cf399efe2081fef7c2c1cd348a78255 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 14 Jul 2026 15:55:02 -0700 Subject: [PATCH 11/18] Update Reference Implementation --- peps/pep-0832.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 2db4d17fccf..0346a994aaa 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -255,10 +255,8 @@ environment in :file:`.python-envs`. Reference Implementation ======================== -The proposed code changes to :mod:`venv` can be found at -https://github.com/brettcannon/cpython/tree/venv-location-pep. A diff showing -the changes can be seen at -https://github.com/brettcannon/cpython/compare/main...brettcannon:cpython:venv-location-pep. +As this PEP proposes no code changes, there is no reference implementation to +speak of. Rejected Ideas From afa974762e442e6cd87f1094789b141ee5424d37 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 16 Jul 2026 16:23:39 -0700 Subject: [PATCH 12/18] Add `.venv` file to Rejected Ideas --- peps/pep-0832.rst | 50 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 0346a994aaa..4eec196028e 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -262,8 +262,11 @@ speak of. Rejected Ideas ============== +``.venv`` +--------- + 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 @@ -275,19 +278,42 @@ PEP, and the author of this PEP prefers the name, ``.venv`` was chosen. Discussing alternative names was viewed as bikeshedding. -Open Issues -=========== +``.python-envs`` +---------------- + +A ``.venv`` redirect file +''''''''''''''''''''''''' + +An earlier version of this PEP allowed for :file:`.venv` to act as a redirect +file to where the virtual environment is located. This was found to be too +restrictive compared to :file:`.python-envs` for a couple of reasons: + +- It supported only a single environment +- It was restricted to only a virtual environment + + +Recording what tool manages an environment +'''''''''''''''''''''''''''''''''''''''''' + +XXX + + +Using a more structured format +'''''''''''''''''''''''''''''' -List all known virtual environments in the redirect file --------------------------------------------------------- +XXX + + + + + +XXX Look for other rejected ideas + + +Deferred Ideas +============== -While the redirect file format is designed for future usage, this PEP could -choose to just use that space now instead of in some future PEP. The extra data -in the file could record other virtual environments that the project has. -Optionally, the path could be separated from a labelled name by a ``\t``. The -default virtual environment would be allowed to be listed in the labelled -section if an explicit label was desired. Another option would to record such -data in a JSON/JSONL trailer in the file. +XXX WSP Acknowledgements From 79add8c5ef1a84932f14dd3406910429331cd69f Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 17 Jul 2026 16:12:46 -0700 Subject: [PATCH 13/18] Fill in more Rejected Ideas --- peps/pep-0832.rst | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 4eec196028e..d8fcba2a3f1 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -295,16 +295,29 @@ restrictive compared to :file:`.python-envs` for a couple of reasons: Recording what tool manages an environment '''''''''''''''''''''''''''''''''''''''''' -XXX +It was suggested to have :file:`.python-envs` record what tool provided an +environment. The thinking was 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 :file:`.python-envs` 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 '''''''''''''''''''''''''''''' -XXX - - - +Using a more structured data format such as JSON for :file:`.python-envs` was +suggested. Typically it was in order to record details about the environment +directly in :file:`.python-envs`. 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. XXX Look for other rejected ideas @@ -328,6 +341,11 @@ this PEP. Change History ============== +- XXX-Jul-2026 + + - Changed from :file:`.venv` redirect files to :file:`.python-envs` + - Dropped all proposed changes to :mod:`venv` + - 23-Apr-2026 - Add PyCharm and library-skills support From 75e24435cca8ce13f2be31dddbe66d392cb571fc Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 27 Jul 2026 16:51:54 -0700 Subject: [PATCH 14/18] Finish Rejected Ideas --- peps/pep-0832.rst | 49 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index d8fcba2a3f1..c5309d0c5e3 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -320,7 +320,54 @@ 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. -XXX Look for other rejected ideas +Storing the locations in pyproject.toml +''''''''''''''''''''''''''''''''''''''' + +It was suggested to store the locations of the environment in +:file:`pyproject.toml`, but that was rejected as too rigid. Typically an +environment location is either a personal choice or a tool 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 +:file:`.python-envs` file. + + +Using the first entry in .python-envs as the default environment +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +It's a subjective choice to have the default environment be at the end of a +:file:`.python-envs` file instead of at the start. The decision came down to +easier reading or writing as the preference. The PEP chose the latter to +optimize for as it's believed by the PEP author that it's more important to +make writing to a :file:`.python-envs` file easier as a person has a greater +chance of doing that than reading (the corollary is since a tool is more likely +to read a :file:`.python-envs` it does not need to be optimized for over a +person). + +As well, the expectation is that reading even a :file:`.python-envs` file with +hundreds of locations will in any way visibly hurt performance. + + +Leave .python-envs out of the PEP +''''''''''''''''''''''''''''''''' + +Some have suggested leaving :file:`.python-envs` out of the PEP (or not having +this PEP at all). But during discussions around this PEP, the desire to have a +way to list the location of multiple environments no matter where they live +seemed strong enough to keep :file:`.python-envs` included. + + +Support a file name suffix for .python-envs +''''''''''''''''''''''''''''''''''''''''''' + +There was a suggestion to allow for multiple :file:`.python-envs`-like files, +differing by a file suffix. The idea was to organize what an environment was +named/for. The idea could also be extended to have the files only contain a +single environment. + +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. Deferred Ideas From 93a590ad617ea554257ae725a26953bd6c4b39c5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 28 Jul 2026 16:18:17 -0700 Subject: [PATCH 15/18] Fill in Deferred Ideas --- peps/pep-0832.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index c5309d0c5e3..e83b6343eb9 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -373,7 +373,18 @@ labels. Finally, it could lead to so many files as to be annoying. Deferred Ideas ============== -XXX WSP +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 From b5b8154fd9e8a07d8c5fe4f91601ecbc028cd65d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 30 Jul 2026 13:48:55 -0700 Subject: [PATCH 16/18] Proofreading --- peps/pep-0832.rst | 68 +++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index e83b6343eb9..280a2593429 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -29,10 +29,10 @@ 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? There's no possible detection of an activated virtual environment via the ``VIRTUAL_ENV`` environment variable -as you didn't launch from a terminal. You potentially could scan all +because you didn't launch it from a terminal. You potentially could scan all subdirectories for a :file:`pyvenv.cfg` file to find a virtual environment, but that assumes the virtual environments are kept locally with the project and -that there is only one of them and not several to ambiguously choose from. +that there is only one of them, rather than several from which to choose. As well, not all projects use virtual environments and may use a different project isolation mechanism like conda environments. @@ -42,7 +42,7 @@ no standardized way to tell anyone where any environments are? Currently, tools like editors have to hard-code a search algorithm for every tool that they choose to support. As well, they can document any conventions they support, but that assumes you or the tool you use to manage your environments -follow those conventions which by being a convention are not written down +follow those conventions, which, being conventions, are not written down anywhere. And this is not a hypothetical issue. The author of this PEP was the dev @@ -60,7 +60,7 @@ The goal of this PEP is to provide a specification for tools which create/manage environments a way to tell other tools where the environments for a project are. And in the case of a project which has multiple 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 one does not want to +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 @@ -72,12 +72,12 @@ Specification ============= This PEP does not define what the "root of a project" means, but the assumption -is it is the directory one would open in their code editor to work on a +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 :file:`pyproject.toml` lives, or potentially the top directory of a monorepo. The virtual environment for a project MAY be a path named :file:`.venv` -(i.e. :file:`.venv/pyvenv.cfg` will exist which can be used to detect the +(i.e. :file:`.venv/pyvenv.cfg` will exist, which can be used to detect the existence of a virtual environment) in the root of the project. This PEP makes no judgment whether :file:`.venv` is a physical or logical path to a directory containing a virtual environment, nor whether logical paths should be resolved @@ -91,7 +91,7 @@ represents an environment that is usable by the project. A trailing newline of either ``\n`` or ``\r\n`` is allowed and MUST be ignored. Lines in a :file:`.python-envs` file MAY be paths to an environment. Paths MAY -be relative, and if they are they are relative they MUST be relative to the +be relative, and if they are, they MUST be relative to the :file:`.python-envs` file. IF a path is for a virtual environment, THEN the path MUST be to the directory of the virtual environment (i.e. the directory containing the :file:`pyvenv.cfg` file). A line MAY represent any type of an @@ -102,7 +102,7 @@ or what type of environment is in a :file:`.python-envs` file. Duplicate lines MAY be in the file. Listing the same environment multiple times does NOT carry any meaning. Any tool MAY remove duplicates at any point, but -UNLESS the last/default environment is being actively changed then that last +UNLESS the last/default environment is being actively changed, that last entry MUST be retained. The last environment listed in a :file:`.python-envs` file MUST be considered @@ -118,7 +118,7 @@ virtual environment. With regard to committing a :file:`.python-envs` file to version control, it MAY be done when the location of the environment(s) is considered static -to a project once it is set up. For instance, some projects that use tox_ have +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 :file:`.python-envs` file to point to that virtual environment and checking in the file is reasonable. The same goes for a project @@ -162,7 +162,7 @@ tool using the same name while still being self-descriptive. The :file:`.python-envs` file is specifically agnostic when it comes to what type of environment can be represented. This helps future-proof the file for -unforseen, future environments. As well, leaving the representation as loose as +unforeseen, future environments. As well, leaving the representation as loose as being what a single line of a file can represent helps with that representation (which can include alternative representations for virtual environments, e.g. connecting over SSH). It does mean, though, that tools @@ -177,7 +177,7 @@ line-delimited file format makes it easy to append a line to a - ``Add-Content .python-envs ""`` - ``python3 -c "import sys; p=sys.argv[1]; open('.python-envs', 'a').write(p)" ""`` -To make appending as simple as a process as possible, duplicate lines are +To make appending as simple a process as possible, duplicate lines are allowed to occur in :file:`.python-envs`. This alleviates having to check the file before appending. This is also why a trailing newline is allowed in the file. @@ -185,19 +185,19 @@ file. 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 for environments, but e.g. virtual environments have the prompt recorded -in :file:`pyvenv.cfg`, to it doesn't need to be listed separate from the +in :file:`pyvenv.cfg`, so it does not need to be listed separately from the environment where it may become stale. This is also why the last line is the default environment: the expectation is people will be adding the environment they want to use and not simply recording an available environment. This all tries to make what is expected to be the -most common action be the easiest action. +most common action the easiest action. Having :file:`.venv` represent the last, and thus default, environment in a :file:`.python-envs` file is for practical reasons. Tools that predate this PEP may use the :file:`.venv` location, and so this is a backwards-compatibility consideration. And if a user is using such a tool that -uses :file:`.venv` then they likely already considered that virtual environment +uses :file:`.venv`, then they likely already considered that virtual environment the default. @@ -223,8 +223,8 @@ compatibility concern as :file:`.venv` is in this PEP specifically for backwards compatibility. As for :file:`.python-envs`, that file name is not known to be in use. The -biggest backwards compatibility concern is a tool producing it and it not -being used as expected. After that is the file not being ignored by version +biggest backwards compatibility concern is that a tool produces it and it is +not used as expected. After that is the file not being ignored by version control upfront. @@ -272,10 +272,10 @@ 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. Since 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 redirect file support as proposed by this -PEP, and the author of this PEP prefers the name, ``.venv`` was chosen. -Discussing alternative names was viewed as bikeshedding. +existing tools seem to already support ``.venv``, and one can still use a +different name for an environment thanks to :file:`.python-envs` as proposed by +this PEP. Because the author of this PEP prefers the name, +``.venv`` was chosen. Discussing alternative names was viewed as bikeshedding. ``.python-envs`` @@ -296,10 +296,10 @@ Recording what tool manages an environment '''''''''''''''''''''''''''''''''''''''''' It was suggested to have :file:`.python-envs` record what tool provided an -environment. The thinking was 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. +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 :file:`.python-envs` for. If a tool wanted to keep @@ -325,9 +325,9 @@ Storing the locations in pyproject.toml It was suggested to store the locations of the environment in :file:`pyproject.toml`, but that was rejected as too rigid. Typically an -environment location is either a personal choice or a tool 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 +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 :file:`.python-envs` file. @@ -336,15 +336,15 @@ Using the first entry in .python-envs as the default environment It's a subjective choice to have the default environment be at the end of a :file:`.python-envs` file instead of at the start. The decision came down to -easier reading or writing as the preference. The PEP chose the latter to -optimize for as it's believed by the PEP author that it's more important to -make writing to a :file:`.python-envs` file easier as a person has a greater -chance of doing that than reading (the corollary is since a tool is more likely -to read a :file:`.python-envs` it does not need to be optimized for over a +whether reading or writing should be preferred. The PEP chose the latter, +as its author believes that it is more important to make writing to a +:file:`.python-envs` file easier, as a person is more likely to do that than +to read it (the corollary is that, since a tool is more likely to read a +:file:`.python-envs` file via code, reading does not need to be optimized for a person). As well, the expectation is that reading even a :file:`.python-envs` file with -hundreds of locations will in any way visibly hurt performance. +hundreds of locations will not visibly hurt performance in any way. Leave .python-envs out of the PEP @@ -408,7 +408,7 @@ Change History - Add PyCharm and library-skills support - Have redirect files read up to the first newline - - Clarify there is no opinion to having multiple virtual environments + - 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 From 28190c6e9edc549a73f40efe93c41d9658df7ded Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 31 Jul 2026 15:38:58 -0700 Subject: [PATCH 17/18] Clarify some details --- peps/pep-0832.rst | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index 280a2593429..a23b469c6ec 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -87,8 +87,9 @@ The root of a project MAY have a :file:`.python-envs` file. This file acts as a listing of all known environments for the project (sans :file:`.venv`; how that and :file:`.python-envs` work together will be covered later). The :file:`.python-envs` MUST be encoded using UTF-8. Each line of the file -represents an environment that is usable by the project. A trailing newline of -either ``\n`` or ``\r\n`` is allowed and MUST be ignored. +represents an environment that is usable by the project and may be separated by +``\n`` or ``\r\n``. A trailing newline of either ``\n`` or ``\r\n`` is allowed +and MUST be ignored. Lines in a :file:`.python-envs` file MAY be paths to an environment. Paths MAY be relative, and if they are, they MUST be relative to the @@ -97,20 +98,25 @@ path MUST be to the directory of the virtual environment (i.e. the directory containing the :file:`pyvenv.cfg` file). A line MAY represent any type of an environment. Tools reading a :file:`.python-envs` MAY choose what sort of environments they support and thus MAY ignore any lines they do not -understand. There are NO other restrictions on how environments are represented -or what type of environment is in a :file:`.python-envs` file. +understand (although there is a specific restriction in regards to the default +environment not being supported; covered later). For environments a tool +understands but are somehow malformed (e.g. a virtual environment whose +symlinks no longer resolve), it is up to the tool to decide how to handle such +a situation. There are NO other restrictions on how environments are +represented or what type of environment is in a :file:`.python-envs` file. An +empty file has NO special meaning other than representing the lack of any +environments. Duplicate lines MAY be in the file. Listing the same environment multiple times -does NOT carry any meaning. Any tool MAY remove duplicates at any point, but -UNLESS the last/default environment is being actively changed, that last -entry MUST be retained. +does NOT carry any meaning. Any tool MAY remove duplicates at any point, but it +MUST maintain what environment is considered the default during de-duplication. The last environment listed in a :file:`.python-envs` file MUST be considered the default environment when a default environment is desired. IF a tool does not support the last environment listed THEN the tool MUST either ask the user which environment to use OR error out. -IF both a virtual environment in a :file:`.venv` path and a +IF both a virtual environment in a :file:`.venv` directory path and a :file:`.python-envs` file exist side-by-side, THEN the :file:`.venv` path MUST be implicitly considered the last line in the :file:`.python-envs` file. This also means the :file:`.venv` virtual environment is considered the default @@ -127,6 +133,9 @@ 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. +Tools MAY use a file system locking mechanism to help guarantee no race +conditions when reading or writing to a :`.python-envs` file. + Rationale ========= @@ -162,12 +171,11 @@ tool using the same name while still being self-descriptive. The :file:`.python-envs` file is specifically agnostic when it comes to what type of environment can be represented. This helps future-proof the file for -unforeseen, future environments. As well, leaving the representation as loose as -being what a single line of a file can represent helps with that -representation (which can include alternative representations for virtual -environments, e.g. connecting over SSH). It does mean, though, that tools -SHOULD check the line for appropriate use (e.g. make sure the environment -location is legitimate before passing it to ``subprocess.run()``). +unforeseen, future environments. As well, leaving the representation as loose +as what a single line of a file can represent helps with allowing alternative +environments that a tool may or may not support (which can include alternative +representations for virtual environments, e.g. connecting over SSH). It does +mean, though, that tools SHOULD check the line for appropriate use. The file format is simple to allow for easy manipulation. Having a line-delimited file format makes it easy to append a line to a From 0efe82c2065d88d2ed20efb7c49fd1e715633b61 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 31 Jul 2026 15:43:06 -0700 Subject: [PATCH 18/18] Set the change history date --- peps/pep-0832.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0832.rst b/peps/pep-0832.rst index a23b469c6ec..2940a30e64e 100644 --- a/peps/pep-0832.rst +++ b/peps/pep-0832.rst @@ -407,7 +407,7 @@ this PEP. Change History ============== -- XXX-Jul-2026 +- 31-Jul-2026 - Changed from :file:`.venv` redirect files to :file:`.python-envs` - Dropped all proposed changes to :mod:`venv`