Will the first source in PYTHONPATH always be searched first?
Question: Will the sources in PYTHONPATH always be searched in the very same order as
they are listed? Or may the order of them change somewhere?

The specific case I'm wondering about is the view of PYTHONPATH before Python
is started and if that differs to how Python actually uses it.


Answer: It's actually moderately complicated. The story starts in the C code, which is
what looks at `$PYTHONPATH` initially, but continues from there.

In all cases, but especially if Python is being invoked as an embedded
interpreter (including "framework" stuff on MacOS X), at least a little bit of
"magic" is done to build up an internal path string. (When embedded, whatever
is running the embedded Python interpreter can call `Py_SetPath`, otherwise
python tries to figure out how it was invoked, then adjust and add
`lib/pythonX.Y` where X and Y are the major and minor version numbers.) This
internal path construction is done so that Python can find its own standard
modules, things like `collections` and `os` and `sys`. `$PYTHONHOME` can also
affect this process. In general, though, the environment `$PYTHONPATH`
variable—unless suppressed via `-E`—winds up in front of the semi-magic
default path.

The whole schmear is used to set the initial value of `sys.path`. But then as
soon as Python starts up, it loads
[`site.py`](http://docs.python.org/2/library/site.html) (unless suppressed via
`-S`). This modifies `sys.path` rather extensively—generally preserving things
imported from `$PYTHONPATH`, in their original order, but shoving a lot of
stuff (like system eggs) in front.1 Moreover, one of the things it does is
load—if it exists—a per-user file
`$HOME/.local/lib/pythonX.Y/sitepackages/usercustomize.py`, and _that_ can do
anything, there are no guarantees:

    
    
    $ cat usercustomize.py
    print 'hello from usercustomize'
    $ python
    hello from usercustomize
    Python 2.7.5 (default, Jun 15 2013, 11:50:00) 
    [GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 
    

If I were to put:

    
    
    import random, sys
    random.shuffle(sys.path)
    

this would scramble `sys.path`, putting `$PYTHONPATH` elements in random
order. Arguably this is a case of "ok, you shot yourself in the foot, that's
_your_ problem". :-) But anything I import can similarly mess with `sys.path`,
so it's possible for something other than my own `usercustomize.py` to ruin
the desired effect (of `$PYTHONPATH` ordering being preserved).

* * *

1 Footnote (late edit): actually the eggs come from `site-packages/site.py`,
which does its own `os.getenv("PYTHONPATH")`. So it's even messier, in a way.
The general principle applies though: standard code _should_ preserve path
order, but you can break it.

