PEP: 370 Title: Per user site-packages directory Author: Christian
Heimes <christian@python.org> Status: Final Type: Standards Track
Content-Type: text/x-rst Created: 11-Jan-2008 Python-Version: 2.6, 3.0
Post-History:

Abstract

This PEP proposes a new a per user site-packages directory to allow
users the local installation of Python packages in their home directory.

Rationale

Current Python versions don't 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[1], Working Env[2] or Virtual Env[3].

It's 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.

The feature can't be implemented using the environment variable
PYTHONPATH. The env var just inserts a new directory to the beginning of
sys.path but it doesn't parse the pth files in the directory. A full
blown site-packages path is required for several applications and Python
eggs.

Specification

site directory (site-packages)

  A directory in sys.path. In contrast to ordinary directories the pth
  files in the directory are processed, too.

user site directory

  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).

  Unix (including Mac OS X)

      ~/.local/lib/python2.6/site-packages

  Windows

      %APPDATA%/Python/Python26/site-packages

user data directory

  Usually the parent directory of the user site directory. It's meant
  for Python version specific data like config files, docs, images and
  translations.

  Unix (including Mac)

      ~/.local/lib/python2.6

  Windows

      %APPDATA%/Python/Python26

user base directory

  It's located inside the user's 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.

  Unix (including Mac)

      ~/.local

  Windows

      %APPDATA%/Python

user script directory

  A directory for binaries and scripts.[4] It's shared across Python
  versions and the destination directory for scripts.

  Unix (including Mac)

      ~/.local/bin

  Windows

      %APPDATA%/Python/Scripts

Windows Notes

On Windows the Application Data directory (aka APPDATA) was chosen
because it is the most designated place for application data. Microsoft
recommends that software doesn't write to USERPROFILE[5] and
My Documents is not suited for application data, either.[6] The code
doesn't query the Win32 API, instead it uses the environment variable
%APPDATA%.

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.[7]

Unix Notes

On Unix ~/.local was chosen in favor over ~/.python because the
directory is already used by several other programs in analogy to
/usr/local.[8][9]

Mac OS X Notes

On Mac OS X Python uses ~/.local directory as well.[10] Framework builds
of Python include ~/Library/Python/2.6/site-packages as an additional
search path.

Implementation

The site module gets a new method adduserpackage() which adds the
appropriate directory to the search path. The directory is not added if
it doesn't 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.

The user site directory is added before the system site directories but
after Python's search paths and PYTHONPATH. 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 PYTHONPATH.

For security reasons the user site directory is not added to sys.path
when the effective user id or group id is not equal to the process uid /
gid[11]. It's an additional barrier against code injection into suid
apps. However Python suid scripts must always use the -E and -s option
or users can sneak in their own code.

The user site directory can be suppressed with a new option -s or the
environment variable PYTHONNOUSERSITE. The feature can be disabled
globally by setting site.ENABLE_USER_SITE to the value False. It must be
set by editing site.py. It can't be altered in sitecustomize.py or
later.

The path to the user base directory can be overwritten with the
environment variable PYTHONUSERBASE. The default location is used when
PYTHONUSERBASE is not set or empty.

distutils.command.install (setup.py install) gets a new argument --user
to install packages in the user site directory. The required directories
are created on demand.

distutils.command.build_ext (setup.py build_ext) gets a new argument
--user 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.

The site module gets two arguments --user-base and --user-site to print
the path to the user base or user site directory to the standard output.
The feature is intended for scripting, e.g.
./configure --prefix $(python2.5 -m site --user-base)

distutils.sysconfig will get methods to access the private variables of
site. (not yet implemented)

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.

Backwards Compatibility

TBD

Reference Implementation

A reference implementation is available in the bug tracker.[12]

Copyright

This document has been placed in the public domain.

References

[6] Initial suggestion for a per user site-packages directory
https://mail.python.org/archives/list/python-dev@python.org/message/V23CUKRH3VCHFLV33ADMHJSM53STPA7I/

[1] Virtual Python
http://peak.telecommunity.com/DevCenter/EasyInstall#creating-a-virtual-python

[2] Working Env https://pypi.org/project/workingenv.py/
https://ianbicking.org/archive/workingenv-revisited.html

[3] Virtual Env https://pypi.org/project/virtualenv/

[4] Discussion about the bin directory
https://mail.python.org/pipermail/python-dev/2008-January/076162.html

[5] MSDN: CSIDL https://learn.microsoft.com/en/windows/win32/shell/csidl

[6] APPDATA discussion
https://mail.python.org/pipermail/python-dev/2008-January/075993.html

[7] Roaming profile on Windows
https://mail.python.org/pipermail/python-dev/2008-January/076256.html

[8] Suggestion of ~/.local/
https://mail.python.org/pipermail/python-dev/2008-January/075985.html

[9] freedesktop.org XGD basedir specs mentions ~/.local
https://www.freedesktop.org/wiki/Specifications/basedir-spec/

[10] ~/.local for Mac and usercustomize file
https://mail.python.org/pipermail/python-dev/2008-January/076236.html

[11] Security concerns and -s option
https://mail.python.org/pipermail/python-dev/2008-January/076130.html

[12] reference implementation
https://github.com/python/cpython/issues/46132
http://svn.python.org/view/sandbox/trunk/pep370