python-peps / pep-0370.txt

PEP: 370
Title: Per user site-packages directory
Version: $Revision$
Last-Modified: $Date$
Author: Christian Heimes <christian(at)cheimes(dot)de>
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. [10]_ 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
recommands that software doesn't write to ``USERPROFILE`` [5]_ and
``My Documents`` is not suited for application data, either. [8]_ 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
adminstrator for more information. [13]_


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``. [7]_ [11]_


Mac OS X Notes
--------------

On Mac OS X Python uses ~/.local directory as well. [12]_ 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 accidently 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 [9]_. 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
dirctory 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 an 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. [4]_


Copyright
=========

This document has been placed in the public domain.


References
==========

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

.. [2]  Working Env
   http://pypi.python.org/pypi/workingenv.py
   http://blog.ianbicking.org/workingenv-revisited.html

.. [3] Virtual Env
   http://pypi.python.org/pypi/virtualenv

.. [4] reference implementation
   http://bugs.python.org/issue1799
   http://svn.python.org/view/sandbox/trunk/pep370

.. [5] MSDN: CSIDL
   http://msdn2.microsoft.com/en-us/library/bb762494.aspx

.. [6] Initial suggestion for a per user site-packages directory
   http://permalink.gmane.org/gmane.comp.python.devel/90902

.. [7] Suggestion of ~/.local/
   http://permalink.gmane.org/gmane.comp.python.devel/90925

.. [8] APPDATA discussion
   http://permalink.gmane.org/gmane.comp.python.devel/90932

.. [9] Security concerns and -s option
   http://permalink.gmane.org/gmane.comp.python.devel/91063

.. [10] Discussion about the bin directory
   http://permalink.gmane.org/gmane.comp.python.devel/91095

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

.. [12] ~/.local for Mac and usercustomize file
   http://permalink.gmane.org/gmane.comp.python.devel/91167

.. [13] Roaming profile on Windows
   http://permalink.gmane.org/gmane.comp.python.devel/91187

..
   Local Variables:
   mode: indented-text
   indent-tabs-mode: nil
   sentence-end-double-space: t
   fill-column: 70
   coding: utf-8
   End:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.