wiki:RootLessInstall
Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Version 1 (modified by dholth@…, 13 years ago) (diff)

less root access is good

I prefer to install turbogears and friends in a user's directory. Here's how I do it:

  1. ~/.pydistutils.cfg tells distutils where to install things. On OS X mine looks like this:
    [install]
    install_lib = ~/Library/Python/$py_version_short/site-packages
    install_data = ~/Library/Python/$py_version_short/site-packages
    # install_headers =
    install_scripts = ~/bin
    
    This tells distutils to install in my home directory, in a directory the *Framework* build (not system Python) of Python for Mac OS X will look for it.

(If I install an extension like numarray it wil include headers, and I may be able to use install_headers to put them in ~/include/ . I have not needed this yet.)

For Linux I use this instead, in a layout that mimics the usual /usr/lib/python?.?/site-packages/ or /usr/local/lib/python?.?/site-packages/:

[install]
install_lib = ~/lib/python$py_version_short/site-packages
install_data = ~/lib/python$py_version_short/site-packages
install_scripts = ~/bin
  1. I really, really like it that Python on OS X automatically looks in my home directory. No more setting PYTHONPATH=$HOME/lib/python2.4/site-packages/ in my ~/.bash_profile , and it works no matter which version of Python I'm using. Besides, PYTHONPATH=... does not tell python to look for eggs or .pth files. So I edit my /usr/lib/python2.4/site.py to do that:
def addsitepackages(known_paths):
    """Add site-packages (and possibly site-python) to sys.path"""
    prefixes = [os.path.join(sys.prefix, "local"), sys.prefix]
    if sys.exec_prefix != sys.prefix:
        prefixes.append(os.path.join(sys.exec_prefix, "local"))
    for prefix in prefixes:
        if prefix:
            if sys.platform in ('os2emx', 'riscos'):
                sitedirs = [os.path.join(prefix, "Lib", "site-packages")]
            elif os.sep == '/':
                sitedirs = [os.path.join(prefix,
                                         "lib",
                                         "python" + sys.version[:3],
                                         "site-packages"),
                            os.path.join(prefix, "lib", "site-python")]
                try:
                    # sys.getobjects only available in --with-pydebug build
                    sys.getobjects
                    sitedirs.insert(0, os.path.join(sitedirs[0], 'debug'))
                except AttributeError:
                    pass
            else:
                sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")]
            if sys.platform == 'darwin':
                # for framework builds *only* we add the standard Apple
                # locations. Currently only per-user, but /Library and
                # /Network/Library could be added too
                if 'Python.framework' in prefix:
                    home = os.environ.get('HOME')
                    if home:
                        sitedirs.append(
                            os.path.join(home,
                                         'Library',
                                         'Python',
                                         sys.version[:3],
                                         'site-packages'))
# ADDED LINES HERE
            home = os.environ.get('HOME')
            if home:
                if not home in sitedirs:
                    sitedirs.append(os.path.join(home,
                                                'lib',
                                                'python' + sys.version[:3],
                                                'site-packages'))

# END OF CHANGE
            for sitedir in sitedirs:
                if os.path.isdir(sitedir):
                    addsitedir(sitedir, known_paths)
    return None