-
-
Save henriquebastos/270cff100cb303f3d74370489022446b to your computer and use it in GitHub Desktop.
"""IPython startup script to detect and inject VIRTUAL_ENV's site-packages dirs. | |
IPython can detect virtualenv's path and injects it's site-packages dirs into sys.path. | |
But it can go wrong if IPython's python version differs from VIRTUAL_ENV's. | |
This module fixes it looking for the actual directories. We use only old stdlib | |
resources so it can work with as many Python versions as possible. | |
References: | |
http://stackoverflow.com/a/30650831/443564 | |
http://stackoverflow.com/questions/122327/how-do-i-find-the-location-of-my-python-site-packages-directory | |
https://github.com/ipython/ipython/blob/master/IPython/core/interactiveshell.py#L676 | |
Author: Henrique Bastos <[email protected]> | |
License: BSD | |
""" | |
import os | |
import sys | |
from warnings import warn | |
virtualenv = os.environ.get('VIRTUAL_ENV') | |
if virtualenv: | |
version = os.listdir(os.path.join(virtualenv, 'lib'))[0] | |
site_packages = os.path.join(virtualenv, 'lib', version, 'site-packages') | |
lib_dynload = os.path.join(virtualenv, 'lib', version, 'lib-dynload') | |
if not (os.path.exists(site_packages) and os.path.exists(lib_dynload)): | |
msg = 'Virtualenv site-packages discovery went wrong for %r' % repr([site_packages, lib_dynload]) | |
warn(msg) | |
try: | |
i = sys.path.index("") + 1 | |
except ValueError: | |
i = 0 | |
sys.path.insert(i, site_packages) | |
sys.path.insert(i+1, lib_dynload) |
Hi,
When using this script, I found that it ignored packages that were installed in 'develop' mode via python setup.py develop
or pip install -e .
. It seems like when something is installed in develop mode, an egg-link is added to the site-packages which points to the active package directory. I'm not sure how this egg-link is resolved normally in python, but at some point that directory is directly added to sys.path
. To mimic this behavior, I added the following anywhere after the variable site_packages
is defined:
egg_links = [i for i in os.listdir(site_packages) if 'egg-link' in i]
for egg in egg_links:
with open(os.path.join(site_packages,egg), 'r') as fin:
sys.path.insert(0, fin.readline().rstrip('\n'))
This simply looks for anything that has 'egg-link' in the name, then opens the file and adds the first line to the path. No idea if you could have an edge case in which there could be multiple paths or lines in the egg-link, but this works for my needs.
I was following your Medium post to get something setup on my machine. I started running into some issues with packages that used
get_distribution
frompkg_resources
(insetup tools
) in their__init__.py
files. The error would look like:It turned out that by the time that the script in this gist was called,
pkg_resources
had already been imported (at least once) before.Its documentation states that:
Thus, the solution that I found (not sure how "correct" it is...) is to:
Add
import pkg_resources
at the top, then add:along with the
sys.path.insert
statements at the end.