The site module documentation and Modifying Python's Search Path seem to be what you're looking for.
As far as I understand it, those entries are being added to sys.path by:
/usr/lib/python2.6/site.py/usr/lib/python2.6/dist-packages/site.py
(Change 2.6 to your version of Python.)
The easiest way to change it is to add a file /usr/local/lib/python2.6/dist-packages/site-packages.pth containing ../site-packages.
Alternatively, maybe you can teach the package to use site.getsitepackages()?
The site module documentation and Modifying Python's Search Path seem to be what you're looking for.
As far as I understand it, those entries are being added to sys.path by:
/usr/lib/python2.6/site.py/usr/lib/python2.6/dist-packages/site.py
(Change 2.6 to your version of Python.)
The easiest way to change it is to add a file /usr/local/lib/python2.6/dist-packages/site-packages.pth containing ../site-packages.
Alternatively, maybe you can teach the package to use site.getsitepackages()?
I'd like to summarize my findings about python's path modification. There are two ways to do it.
- .pth file
PYTHONPATH
Any .pth file which is found on the default path (see bellow) will get its content included into sys.path.
Format of said .pth file is simple: one (folder) path per line. Surprisingly, the paths can be absolute or relative to the .pth file.
Default path is where the interpreter resides and <some-prefix>/lib/python<version>/site-packages where <some-prefix> is usually /usr/.
PYTHONPATH is environmental variable of your operating system. On unix systems you list them by env. Global modification of such variables is done through .sh scripts inside /etc/profile.d/ folder as mentioned by @TestUser16418.
This is working as documented. Any paths specified in PYTHONPATH are documented as normally coming after the working directory but before the standard interpreter-supplied paths. sys.path.append() appends to the existing path. See here and here. If you want a particular directory to come first, simply insert it at the head of sys.path:
import sys
sys.path.insert(0,'/path/to/mod_directory')
That said, there are usually better ways to manage imports than either using PYTHONPATH or manipulating sys.path directly. See, for example, the answers to this question.
You could use:
import os
path = 'the path you want'
os.environ['PATH'] += os.pathsep + path
Sys.path is included in the current directory by default
How to temporarily modify sys.path in Python? - Stack Overflow
Change the priority of python sys.path - Stack Overflow
packages - Best way to set sys.path for "hot library" development in Python? - Software Engineering Stack Exchange
You could use a simple context manager:
import sys
class add_path():
def __init__(self, path):
self.path = path
def __enter__(self):
sys.path.insert(0, self.path)
def __exit__(self, exc_type, exc_value, traceback):
try:
sys.path.remove(self.path)
except ValueError:
pass
Then to import a module you can do:
with add_path('/path/to/dir'):
mod = __import__('mymodule')
On exit from the body of the with statement sys.path will be restored to the original state. If you only use the module within that block you might also want to delete its reference from sys.modules:
del sys.modules['mymodule']
Appending a value to sys.path only modifies it temporarily, i.e for that session only.
Permanent modifications are done by changing PYTHONPATH and the default installation directory.
So, if by temporary you meant for current session only then your approach is okay, but you can remove the pop part if somedir is not hiding any important modules that is expected to be found in in PYTHONPATH ,current directory or default installation directory.
http://docs.python.org/2/tutorial/modules.html#the-module-search-path
As you may know, sys.path is initialized from:
- the current directory
- your
PYTHONPATH - an installation-dependent default
However unfortunately that is only part of the story: setuptools creates easy-install.pth files, which also modify sys.path and worst of all they prepend packages and therefore totally mess up the order of directories.
In particular (at least on my system), there is /usr/local/lib/python2.7/dist-packages/easy-install.pth with the following contents:
import sys; sys.__plen = len(sys.path)
/usr/lib/python2.7/dist-packages
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 causes /usr/lib/python2.7/dist-packages to be prepended even before your PYTHONPATH!
What you could do is simply change the 2nd line in this file to
/usr/local/lib/python2.7/dist-packages
and you will get your desired priority.
However beware this file might be overwritten or changed again by a future setuptools invocation!
We encountered an almost identical situation and wanted to expand upon @kynan's response which is spot-on. In the case where you have such an easy-install.pth that you want to overcome, but which you cannot modify it (say you are a user with no root/admin access), you can do the following:
Set up an alternate python installation scheme
- e.g. we use a PYTHON HOME install (setting PYTHONUSERBASE)
Create a user/home site-packages
- You can do this by installing a package into the user env:
pip install <package> --user
- You can do this by installing a package into the user env:
Create a pth to set
sys.__egginsertto workaround the system/distribution easy-install.pth- Create a
$PYTHONUSERBASE/lib/python2.7/site-packages/fix_easy_install.pth - Containing:
import sys; sys.__egginsert = len(sys.path);
- Create a
This will set sys.__egginsert to point to the end of your sys.path including your usersite paths. When the nefarious system/dist easy-install.pth will then insert its items at the end of the system path.
OK, I started to craft a solution that involved PEP 302 import hooks. Way too complicated.
I think you answered your own question with:
this "gateway" script could implement all manner of bootstrapping functionality - for example, ensuring that virtualenv is set up correctly and activated for the current branch.
if you are already using virtualenv, put the logic you have in the "~/venv/or-whatever-path/bin/activate" script that is already there. I'd suggest listing of possible entry points and prompting for a response (list with numbers and a raw_input() statement will do) if you are not specifying one.
I'd also put the name of your branch in to $PS1 so that is shows up in the tab name or window title of your terminal. I so something similar and change the color of the prompt so I don't do the right thing in the wrong place.
You have to use virtualenv. It create an isolated python environment. It is also recommended when you need different versions of third party packages depending of the version of your product.
Recently, I came to know that some Python guru's prefer not to touch sys.path. I wanted to know if it is safe or unsafe to modify sys.path by appending paths to get them in PYTHONPATH? If it is unsafe then which is better way to get a path in PYTHONPATH?
You can modify the environment variable PYTHONPATH to adjust the default path Python looks for modules when importing.
For instance, to add the directory /home/me/mypy to the path, just do:
import sys
sys.path.append("/home/me/mypy")
source: http://www.johnny-lin.com/cdat_tips/tips_pylang/path.html