Python – What sets up sys.path with Python, and when

pathpython

When I run

import sys 
print sys.path

on my Mac (Mac OS X 10.6.5, Python 2.6.1), I get the following results.

/Library/Python/2.6/site-packages/ply-3.3-py2.6.egg
...
/Library/Python/2.6/site-packages/ipython-0.10.1-py2.6.egg
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python26.zip
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages

/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-old
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload
/Library/Python/2.6/site-packages
/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC
/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/wx-2.8-mac-unicode

They are grouped into 5 categories.

  • /Library/Python/2.6/site-packages/*.egg
  • /Library/Python/2.6/site-packages
  • Frameworks/Python.framework/Versions/2.6/lib/python2.6
  • Frameworks/Python.framework/Versions/2.6/Extras/lib/python
  • PATH from PYTHONPATH environment variable.

And I can add more paths using the code

sys.path.insert(0, MORE_PATH)
  • What routines sets up those paths, and when?
  • Are some of the paths are built in python source code?
  • Is it possible that the paths inserted with 'sys.path.insert' are ignored? I'm curious about this, as with mod_wsgi, I found the paths are not found with 'sys.path.insert'. I asked another post for this question.

ADDED

Based on Michael's answer, I looked into site.py, and I got the following code.

def addsitepackages(known_paths):
    """Add site-packages (and possibly site-python) to sys.path"""
    sitedirs = []
    seen = []

    for prefix in PREFIXES:
        if not prefix or prefix in seen:
            continue
        seen.append(prefix)

        if sys.platform in ('os2emx', 'riscos'):
            sitedirs.append(os.path.join(prefix, "Lib", "site-packages"))
        elif sys.platform == 'darwin' and prefix == sys.prefix:
            sitedirs.append(os.path.join("/Library/Python", sys.version[:3], "site-packages"))

I also think that the directory name that has site.py (/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6 for my Mac) should be built into Python source code.

Best Answer

Most of the stuff is set up in Python's site.py which is automatically imported when starting the interpreter (unless you start it with the -S option). Few paths are set up in the interpreter itself during initialization (you can find out which by starting python with -S).

Additionally, some frameworks (like Django I think) modify sys.path upon startup to meet their requirements.

The site module has a pretty good documentation, a commented source code and prints out some information if you run it via python -m site.