Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python paths and import order

Tags:

python

I really want to get this right because I keep running into it when generating some big py2app/py2exe packages. I have my package that contains a lot of modules/packages that might also be in the users site packages/default location (if a user has a python distribution) but I want my distributed packages to take effect before them when running from my distribution.

Now from what I've read here PYTHONPATH should be the first thing added to sys.path after the current directory, however from what I've tested on my machine that is not the case and all the folders defined in $site-packages$/easy-install.pth take precedence over this.

Could someone please give me some more in-depth explanation about this import order and help me find a way to set the environmental variables in such a way that the packages I distribute take precedence over the default installed ones?

So far my attempt is, for example on Mac-OS py2app, in my entry point script:

 os.environ['PYTHONPATH'] = DATA_PATH + ':'  os.environ['PYTHONPATH'] = os.environ['PYTHONPATH'] + os.path.join(DATA_PATH                                                             , 'lib') + ':'  os.environ['PYTHONPATH'] = os.environ['PYTHONPATH'] + os.path.join(                                 DATA_PATH, 'lib', 'python2.7', 'site-packages') + ':'  os.environ['PYTHONPATH'] = os.environ['PYTHONPATH'] + os.path.join(                           DATA_PATH, 'lib', 'python2.7', 'site-packages.zip') 

This is basically the structure of the package generated by py2app. Then I just:

 SERVER = subprocess.Popen([PYTHON_EXE_PATH, '-m', 'bin.rpserver'                             , cfg.RPC_SERVER_IP, cfg.RPC_SERVER_PORT],                             shell=False, stdin=IN_FILE, stdout=OUT_FILE,                              stderr=ERR_FILE) 

Here PYTHON_EXE_PATH is the path to the python executable that is added by py2app to the package. This works fine on a machine that doesn't have a python installed. However, when python distribution is already present, its site-packages take precedence.

like image 408
Bogdan Avatar asked Mar 06 '12 15:03

Bogdan


People also ask

Does the order of imports matter in Python?

Import order does not matter. If a module relies on other modules, it needs to import them itself. Python treats each . py file as a self-contained unit as far as what's visible in that file.

How do I order imports in Python?

Imports should be grouped in the following order: standard library imports. related third party imports. local application/library specific imports.


1 Answers

Python searches the paths in sys.path in order (see http://docs.python.org/tutorial/modules.html#the-module-search-path). easy_install changes this list directly (see the last line in your easy-install.pth file):

import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new) 

This basically takes whatever directories are added and inserts them at the beginning of the list.

Also see Eggs in path before PYTHONPATH environment variable.

like image 181
cwa Avatar answered Oct 01 '22 07:10

cwa