Problem description:
Using pip, I upgraded to the latest version of requests (version 2.7.0, with pip show requests
giving the location /usr/local/lib/python2.7/dist-packages
). When I import requests
and print requests.__version__
in the interactive command line, though, I am seeing version 2.2.1. It turns out that Python is using the pre-installed Ubuntu version of requests (requests.__file__
is /usr/lib/python2.7/dist-packages/requests/__init__.pyc
-- not /user/local/lib/...
).
From my investigation, this fact is caused by Ubuntu's changes to the Python search path (I run Ubuntu 14.04) by prepending the path to Ubuntu's Python package (for my machine, this happens in usr/local/lib/python2.7/dist-packages/easy-install.pth
). In my case, this causes the apt-get
version of requests, which is pre-packaged with Ubuntu, to be used, rather than the pip version I want to use.
What I'm looking for:
I want to globally prepend pip's installation directory path to Python's search path (sys.path
), before the path to Ubuntu's Python installation directory. Since requests (and many other packages) are used in many Python scripts of mine, I don't want to manually change the search path for every single file on my machine.
Unsatisfactory Solution 1: Using virtualenv
Using virtualenv would cause an unnecessary amount of change to my machine, since I would have to reinstall every package that exists globally. I only want to upgrade from Ubuntu's packages to pip's packages.
Unsatisfactory Solution 2: Changing easy-install.pth
Since easy-install.pth
is overwritten every time easy-install
is used, my changes to easy-install.pth
would be removed if a new package is installed. This problem makes it difficult to maintain the packages on my machine.
Unsatisfactory (but best one I have so far) Solution 3: Adding a separate .pth file
In the same directory as easy-install.pth I added a zzz.pth
with contents:
import sys; sys.__plen = len(sys.path)
/usr/lib/python2.7/dist-packages/test_dir
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 file is read by site.py
when Python is starting. Since its file name comes after easy-install.pth
alphanumerically, it is consumed by site.py
afterwards. Taken together, the first and last lines of the file prepend the path to sys.path
(these lines were taken from easy-install.pth
).
I don't like how this solution depends on the alphanumeric ordering of the file name to correctly place the new path.
PYTHONPATHs come after Ubuntu's paths
Another answer on Stack Overflow didn't work for me. My PYTHONPATH
paths come after the paths in easy-install.pth
, which uses the same code I mention in "Unsatisfactory solution 3" to prepend its paths.
Thank you in advance!
This is not recommended, as it hard-codes a path and makes it difficult to run the script elsewhere, but you can do
>>> import sys
>>> sys.path.insert(0,'/home/anand/')
>>> print(sys.path)
['/home/anand/', '', '/usr/local/lib/python2.7/dist-packages/_pdbpp_path_hack', '/usr/local/lib/python2.7/dist-packages/goose-0.0.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/jieba-0.33-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/cssselect-0.9.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/nanoservice-0.1.5-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/nanomsg-1.0a2-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/msgpack_python-0.4.2-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/DecisionTree-2.2.5-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/nudepy-0.2-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/wsgilog-0.3-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/distribute-0.7.3-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/PIL-1.1.7-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/munkres-1.0.7-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/parsedatetime-1.4-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/argparse-1.3.0-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/tusker-0.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/SQLAlchemy-1.0.3-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/numpy-1.9.2-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/turkic-0.2.5-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/scikits.bootstrap-0.3.2-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/pyvision-0.1-py2.7-linux-x86_64.egg', '/home/anand/playspace/languages/python_pkgs/ets', '/usr/local/lib/python2.7/dist-packages/Scrapy-1.1.0dev1-py2.7.egg', '/usr/lib/python2.7/dist-packages', '/home/anand/playspace', '/home/anand/workspace/pyvision/src', '/home/anand/playspace/yapf', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages/Orange/orng', '/usr/local/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk2']
>>>
After this your imports will look into the prepended path before looking anywhere else.