python-peps/pep-0370/index.html

353 lines
24 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 370 Per user site-packages directory | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0370/">
<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 370 Per user site-packages directory | peps.python.org'>
<meta property="og:description" content="This PEP proposes a new a per user site-packages directory to allow users the local installation of Python packages in their home directory.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0370/">
<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="This PEP proposes a new a per user site-packages directory to allow users the local installation of Python packages in their home directory.">
<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 370</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 370 Per user site-packages directory</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Christian Heimes &lt;christian&#32;&#97;t&#32;python.org&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">11-Jan-2008</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">2.6, 3.0</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even"><p></p></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="#specification">Specification</a><ul>
<li><a class="reference internal" href="#windows-notes">Windows Notes</a></li>
<li><a class="reference internal" href="#unix-notes">Unix Notes</a></li>
<li><a class="reference internal" href="#mac-os-x-notes">Mac OS X Notes</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
<li><a class="reference internal" href="#references">References</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP proposes a new a per user site-packages directory to allow
users the local installation of Python packages in their home directory.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>Current Python versions dont have a unified way to install packages
into the home directory of a user (except for Mac Framework
builds). Users are either forced to ask the system administrator to
install or update a package for them or to use one of the many
workarounds like Virtual Python <a class="footnote-reference brackets" href="#id13" id="id1">[1]</a>, Working Env <a class="footnote-reference brackets" href="#id14" id="id2">[2]</a> or
Virtual Env <a class="footnote-reference brackets" href="#id15" id="id3">[3]</a>.</p>
<p>Its not the goal of the PEP to replace the tools or to implement
isolated installations of Python. It only implements the most common
use case of an additional site-packages directory for each user.</p>
<p>The feature cant be implemented using the environment variable
<em>PYTHONPATH</em>. The env var just inserts a new directory to the beginning
of <em>sys.path</em> but it doesnt parse the pth files in the directory. A
full blown site-packages path is required for several applications
and Python eggs.</p>
</section>
<section id="specification">
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
<p>site directory (site-packages)</p>
<blockquote>
<div>A directory in <code class="docutils literal notranslate"><span class="pre">sys.path</span></code>. In contrast to ordinary directories the pth
files in the directory are processed, too.</div></blockquote>
<p>user site directory</p>
<blockquote>
<div>A site directory inside the users home directory. A user site
directory is specific to a Python version. The path contains
the version number (major and minor only).<dl class="simple">
<dt>Unix (including Mac OS X)</dt><dd><code class="docutils literal notranslate"><span class="pre">~/.local/lib/python2.6/site-packages</span></code></dd>
<dt>Windows</dt><dd><code class="docutils literal notranslate"><span class="pre">%APPDATA%/Python/Python26/site-packages</span></code></dd>
</dl>
</div></blockquote>
<p>user data directory</p>
<blockquote>
<div>Usually the parent directory of the user site directory. Its meant
for Python version specific data like config files, docs, images
and translations.<dl class="simple">
<dt>Unix (including Mac)</dt><dd><code class="docutils literal notranslate"><span class="pre">~/.local/lib/python2.6</span></code></dd>
<dt>Windows</dt><dd><code class="docutils literal notranslate"><span class="pre">%APPDATA%/Python/Python26</span></code></dd>
</dl>
</div></blockquote>
<p>user base directory</p>
<blockquote>
<div>Its located inside the users home directory. The user site and
use config directory are inside the base directory. On some systems
the directory may be shared with 3rd party apps.<dl class="simple">
<dt>Unix (including Mac)</dt><dd><code class="docutils literal notranslate"><span class="pre">~/.local</span></code></dd>
<dt>Windows</dt><dd><code class="docutils literal notranslate"><span class="pre">%APPDATA%/Python</span></code></dd>
</dl>
</div></blockquote>
<p>user script directory</p>
<blockquote>
<div>A directory for binaries and scripts. <a class="footnote-reference brackets" href="#id21" id="id4">[10]</a> Its shared across Python
versions and the destination directory for scripts.<dl class="simple">
<dt>Unix (including Mac)</dt><dd><code class="docutils literal notranslate"><span class="pre">~/.local/bin</span></code></dd>
<dt>Windows</dt><dd><code class="docutils literal notranslate"><span class="pre">%APPDATA%/Python/Scripts</span></code></dd>
</dl>
</div></blockquote>
<section id="windows-notes">
<h3><a class="toc-backref" href="#windows-notes" role="doc-backlink">Windows Notes</a></h3>
<p>On Windows the <em>Application Data</em> directory (aka <code class="docutils literal notranslate"><span class="pre">APPDATA</span></code>) was chosen
because it is the most designated place for application data. Microsoft
recommends that software doesnt write to <code class="docutils literal notranslate"><span class="pre">USERPROFILE</span></code> <a class="footnote-reference brackets" href="#id17" id="id5">[5]</a> and
<code class="docutils literal notranslate"><span class="pre">My</span> <span class="pre">Documents</span></code> is not suited for application data, either. <a class="footnote-reference brackets" href="#id19" id="id6">[8]</a> The code
doesnt query the Win32 API, instead it uses the environment variable
%APPDATA%.</p>
<p>The application data directory is part of the roaming profile. In networks
with domain logins the application data may be copied from and to the a
central server. This can slow down log-in and log-off. Users can keep
the data on the server by e.g. setting PYTHONUSERBASE to the value
“%HOMEDRIVE%%HOMEPATH%Applicata Data”. Users should consult their local
administrator for more information. <a class="footnote-reference brackets" href="#id24" id="id7">[13]</a></p>
</section>
<section id="unix-notes">
<h3><a class="toc-backref" href="#unix-notes" role="doc-backlink">Unix Notes</a></h3>
<p>On Unix <code class="docutils literal notranslate"><span class="pre">~/.local</span></code> was chosen in favor over <code class="docutils literal notranslate"><span class="pre">~/.python</span></code> because the
directory is already used by several other programs in analogy to
<code class="docutils literal notranslate"><span class="pre">/usr/local</span></code>. <a class="footnote-reference brackets" href="#id18" id="id8">[7]</a> <a class="footnote-reference brackets" href="#id22" id="id9">[11]</a></p>
</section>
<section id="mac-os-x-notes">
<h3><a class="toc-backref" href="#mac-os-x-notes" role="doc-backlink">Mac OS X Notes</a></h3>
<p>On Mac OS X Python uses ~/.local directory as well. <a class="footnote-reference brackets" href="#id23" id="id10">[12]</a> Framework builds
of Python include <code class="docutils literal notranslate"><span class="pre">~/Library/Python/2.6/site-packages</span></code> as an additional
search path.</p>
</section>
</section>
<section id="implementation">
<h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2>
<p>The site module gets a new method <code class="docutils literal notranslate"><span class="pre">adduserpackage()</span></code> which adds the
appropriate directory to the search path. The directory is not added if
it doesnt exist when Python is started. However the location of the
user site directory and user base directory is stored in an internal
variable for distutils.</p>
<p>The user site directory is added before the system site directories
but after Pythons search paths and <code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code>. This setup allows
the user to install a different version of a package than the system
administrator but it prevents the user from accidentally overwriting a
stdlib module. Stdlib modules can still be overwritten with
<code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code>.</p>
<p>For security reasons the user site directory is <em>not</em> added to
<code class="docutils literal notranslate"><span class="pre">sys.path</span></code> when the effective user id or group id is not equal to the
process uid / gid <a class="footnote-reference brackets" href="#id20" id="id11">[9]</a>. Its an additional barrier against code injection
into suid apps. However Python suid scripts <em>must</em> always use the -E
and -s option or users can sneak in their own code.</p>
<p>The user site directory can be suppressed with a new option <code class="docutils literal notranslate"><span class="pre">-s</span></code> or
the environment variable <code class="docutils literal notranslate"><span class="pre">PYTHONNOUSERSITE</span></code>. The feature can be
disabled globally by setting <code class="docutils literal notranslate"><span class="pre">site.ENABLE_USER_SITE</span></code> to the value
<code class="docutils literal notranslate"><span class="pre">False</span></code>. It must be set by editing <code class="docutils literal notranslate"><span class="pre">site.py</span></code>. It cant be altered
<code class="docutils literal notranslate"><span class="pre">in</span> <span class="pre">sitecustomize.py</span></code> or later.</p>
<p>The path to the user base directory can be overwritten with the
environment variable <code class="docutils literal notranslate"><span class="pre">PYTHONUSERBASE</span></code>. The default location is used
when <code class="docutils literal notranslate"><span class="pre">PYTHONUSERBASE</span></code> is not set or empty.</p>
<p><code class="docutils literal notranslate"><span class="pre">distutils.command.install</span></code> (setup.py install) gets a new argument
<code class="docutils literal notranslate"><span class="pre">--user</span></code> to install packages in the user site directory. The required
directories are created on demand.</p>
<p><code class="docutils literal notranslate"><span class="pre">distutils.command.build_ext</span></code> (setup.py build_ext) gets a new argument
<code class="docutils literal notranslate"><span class="pre">--user</span></code> which adds the include/ and lib/ directories in the user base
directory to the search paths for header files and libraries. It also
adds the lib/ directory to rpath.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">site</span></code> module gets two arguments <code class="docutils literal notranslate"><span class="pre">--user-base</span></code> and <code class="docutils literal notranslate"><span class="pre">--user-site</span></code>
to print the path to the user base or user site directory to the standard
output. The feature is intended for scripting, e.g.
<code class="docutils literal notranslate"><span class="pre">./configure</span> <span class="pre">--prefix</span> <span class="pre">$(python2.5</span> <span class="pre">-m</span> <span class="pre">site</span> <span class="pre">--user-base)</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">distutils.sysconfig</span></code> will get methods to access the private variables
of site. (not yet implemented)</p>
<p>The Windows updater needs to be updated, too. It should create a menu
item which opens the user site directory in a new explorer windows.</p>
</section>
<section id="backwards-compatibility">
<h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2>
<p>TBD</p>
</section>
<section id="reference-implementation">
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
<p>A reference implementation is available in the bug tracker. <a class="footnote-reference brackets" href="#id16" id="id12">[4]</a></p>
</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 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="id13" role="doc-footnote">
<dt class="label" id="id13">[<a href="#id1">1</a>]</dt>
<dd>Virtual Python
<a class="reference external" href="http://peak.telecommunity.com/DevCenter/EasyInstall#creating-a-virtual-python">http://peak.telecommunity.com/DevCenter/EasyInstall#creating-a-virtual-python</a></aside>
<aside class="footnote brackets" id="id14" role="doc-footnote">
<dt class="label" id="id14">[<a href="#id2">2</a>]</dt>
<dd>Working Env
<a class="reference external" href="https://pypi.org/project/workingenv.py/">https://pypi.org/project/workingenv.py/</a>
<a class="reference external" href="https://ianbicking.org/archive/workingenv-revisited.html">https://ianbicking.org/archive/workingenv-revisited.html</a></aside>
<aside class="footnote brackets" id="id15" role="doc-footnote">
<dt class="label" id="id15">[<a href="#id3">3</a>]</dt>
<dd>Virtual Env
<a class="reference external" href="https://pypi.org/project/virtualenv/">https://pypi.org/project/virtualenv/</a></aside>
<aside class="footnote brackets" id="id16" role="doc-footnote">
<dt class="label" id="id16">[<a href="#id12">4</a>]</dt>
<dd>reference implementation
<a class="reference external" href="https://github.com/python/cpython/issues/46132">https://github.com/python/cpython/issues/46132</a>
<a class="reference external" href="http://svn.python.org/view/sandbox/trunk/pep370">http://svn.python.org/view/sandbox/trunk/pep370</a></aside>
<aside class="footnote brackets" id="id17" role="doc-footnote">
<dt class="label" id="id17">[<a href="#id5">5</a>]</dt>
<dd>MSDN: CSIDL
<a class="reference external" href="https://learn.microsoft.com/en/windows/win32/shell/csidl">https://learn.microsoft.com/en/windows/win32/shell/csidl</a></aside>
</aside>
<p>[6] Initial suggestion for a per user site-packages directory
<a class="reference external" href="https://mail.python.org/archives/list/python-dev&#64;python.org/message/V23CUKRH3VCHFLV33ADMHJSM53STPA7I/">https://mail.python.org/archives/list/python-dev&#64;python.org/message/V23CUKRH3VCHFLV33ADMHJSM53STPA7I/</a></p>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id18" role="doc-footnote">
<dt class="label" id="id18">[<a href="#id8">7</a>]</dt>
<dd>Suggestion of ~/.local/
<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2008-January/075985.html">https://mail.python.org/pipermail/python-dev/2008-January/075985.html</a></aside>
<aside class="footnote brackets" id="id19" role="doc-footnote">
<dt class="label" id="id19">[<a href="#id6">8</a>]</dt>
<dd>APPDATA discussion
<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2008-January/075993.html">https://mail.python.org/pipermail/python-dev/2008-January/075993.html</a></aside>
<aside class="footnote brackets" id="id20" role="doc-footnote">
<dt class="label" id="id20">[<a href="#id11">9</a>]</dt>
<dd>Security concerns and -s option
<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2008-January/076130.html">https://mail.python.org/pipermail/python-dev/2008-January/076130.html</a></aside>
<aside class="footnote brackets" id="id21" role="doc-footnote">
<dt class="label" id="id21">[<a href="#id4">10</a>]</dt>
<dd>Discussion about the bin directory
<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2008-January/076162.html">https://mail.python.org/pipermail/python-dev/2008-January/076162.html</a></aside>
<aside class="footnote brackets" id="id22" role="doc-footnote">
<dt class="label" id="id22">[<a href="#id9">11</a>]</dt>
<dd>freedesktop.org XGD basedir specs mentions ~/.local
<a class="reference external" href="https://www.freedesktop.org/wiki/Specifications/basedir-spec/">https://www.freedesktop.org/wiki/Specifications/basedir-spec/</a></aside>
<aside class="footnote brackets" id="id23" role="doc-footnote">
<dt class="label" id="id23">[<a href="#id10">12</a>]</dt>
<dd>~/.local for Mac and usercustomize file
<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2008-January/076236.html">https://mail.python.org/pipermail/python-dev/2008-January/076236.html</a></aside>
<aside class="footnote brackets" id="id24" role="doc-footnote">
<dt class="label" id="id24">[<a href="#id7">13</a>]</dt>
<dd>Roaming profile on Windows
<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2008-January/076256.html">https://mail.python.org/pipermail/python-dev/2008-January/076256.html</a></aside>
</aside>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0370.rst">https://github.com/python/peps/blob/main/peps/pep-0370.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0370.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="#specification">Specification</a><ul>
<li><a class="reference internal" href="#windows-notes">Windows Notes</a></li>
<li><a class="reference internal" href="#unix-notes">Unix Notes</a></li>
<li><a class="reference internal" href="#mac-os-x-notes">Mac OS X Notes</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
<li><a class="reference internal" href="#references">References</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0370.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>