python-peps/pep-0486/index.html

251 lines
17 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 486 Make the Python Launcher aware of virtual environments | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0486/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 486 Make the Python Launcher aware of virtual environments | peps.python.org'>
<meta property="og:description" content="The Windows installers for Python include a launcher that locates the correct Python interpreter to run (see PEP 397). However, the launcher is not aware of virtual environments (virtualenv 1 or PEP 405 based), and so cannot be used to run commands fro...">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0486/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="The Windows installers for Python include a launcher that locates the correct Python interpreter to run (see PEP 397). However, the launcher is not aware of virtual environments (virtualenv 1 or PEP 405 based), and so cannot be used to run commands fro...">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 486</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 486 Make the Python Launcher aware of virtual environments</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Paul Moore &lt;p.f.moore&#32;&#97;t&#32;gmail.com&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">12-Feb-2015</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">3.5</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even">12-Feb-2015</dd>
<dt class="field-odd">Resolution<span class="colon">:</span></dt>
<dd class="field-odd"><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2015-February/138579.html">Python-Dev message</a></dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#impact-on-script-launching">Impact on Script Launching</a></li>
<li><a class="reference internal" href="#exclusions">Exclusions</a></li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>The Windows installers for Python include a launcher that locates the
correct Python interpreter to run (see <a class="pep reference internal" href="../pep-0397/" title="PEP 397 Python launcher for Windows">PEP 397</a>). However, the
launcher is not aware of virtual environments (virtualenv <a class="footnote-reference brackets" href="#id2" id="id1">[1]</a> or PEP
405 based), and so cannot be used to run commands from the active
virtualenv.</p>
<p>This PEP proposes making the launcher “virtualenv aware”. This means
that when run without specifying an explicit Python interpreter to
use, the launcher will use the currently active virtualenv, if any,
before falling back to the configured default Python.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>Windows users with multiple copies of Python installed need a means of
selecting which one to use. The Python launcher provides this
facility by means of a <code class="docutils literal notranslate"><span class="pre">py</span></code> command that can be used to run either a
configured “default” Python or a specific interpreter, by means of
command line arguments. So typical usage would be:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Run the Python interactive interpreter</span>
<span class="n">py</span>
<span class="c1"># Execute an installed module</span>
<span class="n">py</span> <span class="o">-</span><span class="n">m</span> <span class="n">pip</span> <span class="n">install</span> <span class="n">pytest</span>
<span class="n">py</span> <span class="o">-</span><span class="n">m</span> <span class="n">pytest</span>
</pre></div>
</div>
<p>When using virtual environments, the <code class="docutils literal notranslate"><span class="pre">py</span></code> launcher is unaware that a
virtualenv is active, and will continue to use the system Python. So
different command invocations are needed to run the same commands in a
virtualenv:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Run the Python interactive interpreter</span>
<span class="n">python</span>
<span class="c1"># Execute an installed module (these could use python -m,</span>
<span class="c1"># which is longer to type but is a little more similar to the</span>
<span class="c1"># launcher approach)</span>
<span class="n">pip</span> <span class="n">install</span> <span class="n">pytest</span>
<span class="n">py</span><span class="o">.</span><span class="n">test</span>
</pre></div>
</div>
<p>Having to use different commands is error-prone, and in many cases
the error is difficult to spot immediately. The PEP proposes making
the <code class="docutils literal notranslate"><span class="pre">py</span></code> command usable with virtual environments, so that the first
form of command can be used in all cases.</p>
</section>
<section id="implementation">
<h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2>
<p>Both <code class="docutils literal notranslate"><span class="pre">virtualenv</span></code> and the core <code class="docutils literal notranslate"><span class="pre">venv</span></code> module set an environment
variable <code class="docutils literal notranslate"><span class="pre">VIRTUAL_ENV</span></code> when activating a virtualenv. This PEP
proposes that the launcher checks for the <code class="docutils literal notranslate"><span class="pre">VIRTUAL_ENV</span></code> environment
variable whenever it would run the “default” Python interpreter for
the system (i.e., when no specific version flags such as <code class="docutils literal notranslate"><span class="pre">py</span> <span class="pre">-2.7</span></code>
are used) and if present, run the Python interpreter for the
virtualenv rather than the default system Python.</p>
<p>The “default” Python interpreter referred to above is (as per <a class="pep reference internal" href="../pep-0397/" title="PEP 397 Python launcher for Windows">PEP 397</a>)
either the latest version of Python installed on the system, or
a version configured via the <code class="docutils literal notranslate"><span class="pre">py.ini</span></code> configuration file. When the
user specifies an explicit Python version on the command line, this
will always be used (as at present).</p>
</section>
<section id="impact-on-script-launching">
<h2><a class="toc-backref" href="#impact-on-script-launching" role="doc-backlink">Impact on Script Launching</a></h2>
<p>As well as interactive use, the launcher is used as the Windows file
association for Python scripts. In that case, a “shebang” (<code class="docutils literal notranslate"><span class="pre">#!</span></code>)
line at the start of the script is used to identify the interpreter to
run. A fully-qualified path can be used, or a version-specific Python
(<code class="docutils literal notranslate"><span class="pre">python3</span></code> or <code class="docutils literal notranslate"><span class="pre">python2</span></code>, or even <code class="docutils literal notranslate"><span class="pre">python3.5</span></code>), or the generic
<code class="docutils literal notranslate"><span class="pre">python</span></code>, which means to use the default interpreter.</p>
<p>The launcher also looks for the specific shebang line
<code class="docutils literal notranslate"><span class="pre">#!/usr/bin/env</span> <span class="pre">python</span></code>. On Unix, the <code class="docutils literal notranslate"><span class="pre">env</span></code> program searches for a
command on <code class="docutils literal notranslate"><span class="pre">$PATH</span></code> and runs the command so located. Similarly, with
this shebang line, the launcher will look for a copy of <code class="docutils literal notranslate"><span class="pre">python.exe</span></code>
on the users current <code class="docutils literal notranslate"><span class="pre">%PATH%</span></code> and will run that copy.</p>
<p>As activating a virtualenv means that it is added to <code class="docutils literal notranslate"><span class="pre">PATH</span></code>, no
special handling is needed to run scripts with the active virtualenv -
they just need to use the <code class="docutils literal notranslate"><span class="pre">#!/usr/bin/env</span> <span class="pre">python</span></code> shebang line,
exactly as on Unix. (If there is no activated virtualenv, and no
<code class="docutils literal notranslate"><span class="pre">python.exe</span></code> on <code class="docutils literal notranslate"><span class="pre">PATH</span></code>, the launcher will look for a default
Python exactly as if the shebang line had said <code class="docutils literal notranslate"><span class="pre">#!python</span></code>).</p>
</section>
<section id="exclusions">
<h2><a class="toc-backref" href="#exclusions" role="doc-backlink">Exclusions</a></h2>
<p>The PEP makes no attempt to promote the use of the launcher for
running Python on Windows. Most existing documentation assumes the
user of <code class="docutils literal notranslate"><span class="pre">python</span></code> as the command to run Python, and (for example)
<code class="docutils literal notranslate"><span class="pre">pip</span></code> to run an installed Python command. This documentation is not
expected to change, and users who choose to manage their <code class="docutils literal notranslate"><span class="pre">PATH</span></code>
environment variable can continue to use this form. The focus of this
PEP is purely on allowing users who prefer to use the launcher when
dealing with their system Python installations, to be able to continue
to do so when using virtual environments.</p>
</section>
<section id="reference-implementation">
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
<p>A patch implementing the proposed behaviour is available at
<a class="reference external" href="http://bugs.python.org/issue23465">http://bugs.python.org/issue23465</a></p>
</section>
<section id="references">
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id2" role="doc-footnote">
<dt class="label" id="id2">[<a href="#id1">1</a>]</dt>
<dd><a class="reference external" href="https://virtualenv.pypa.io/">https://virtualenv.pypa.io/</a></aside>
</aside>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0486.rst">https://github.com/python/peps/blob/main/peps/pep-0486.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0486.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#impact-on-script-launching">Impact on Script Launching</a></li>
<li><a class="reference internal" href="#exclusions">Exclusions</a></li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0486.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>