##// END OF EJS Templates
Introduce pathlib on init_virtualenv.
Gabriel Simonetto -
Show More
@@ -28,6 +28,7 b' import subprocess'
28 28 import warnings
29 29 from io import open as io_open
30 30
31 from pathlib import Path
31 32 from pickleshare import PickleShareDB
32 33
33 34 from traitlets.config.configurable import SingletonConfigurable
@@ -889,7 +890,7 b' class InteractiveShell(SingletonConfigurable):'
889 890 self.display_trap = DisplayTrap(hook=self.displayhook)
890 891
891 892 def init_virtualenv(self):
892 """Add a virtualenv to sys.path so the user can import modules from it.
893 """Add the current virtualenv to sys.path so the user can import modules from it.
893 894 This isn't perfect: it doesn't use the Python interpreter with which the
894 895 virtualenv was built, and it ignores the --no-site-packages option. A
895 896 warning will appear suggesting the user installs IPython in the
@@ -902,24 +903,21 b' class InteractiveShell(SingletonConfigurable):'
902 903 if 'VIRTUAL_ENV' not in os.environ:
903 904 # Not in a virtualenv
904 905 return
905
906 p = os.path.normcase(sys.executable)
907 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
908
909 # executable path should end like /bin/python or \\scripts\\python.exe
910 p_exe_up2 = os.path.dirname(os.path.dirname(p))
911 if p_exe_up2 and os.path.exists(p_venv) and os.path.samefile(p_exe_up2, p_venv):
912 # Our exe is inside the virtualenv, don't need to do anything.
906 elif os.environ['VIRTUAL_ENV'] == '':
907 warn("Virtual env path set to '', please check if this is intended.")
913 908 return
914 909
910 p = Path(sys.executable)
911 p_venv = Path(os.environ['VIRTUAL_ENV'])
912
915 913 # fallback venv detection:
916 914 # stdlib venv may symlink sys.executable, so we can't use realpath.
917 915 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
918 916 # So we just check every item in the symlink tree (generally <= 3)
919 917 paths = [p]
920 while os.path.islink(p):
921 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
922 paths.append(p)
918 while p.is_symlink():
919 p = Path(os.readlink(p))
920 paths.append(p.resolve())
923 921
924 922 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
925 923 if p_venv.startswith('\\cygdrive'):
@@ -927,17 +925,23 b' class InteractiveShell(SingletonConfigurable):'
927 925 elif len(p_venv) >= 2 and p_venv[1] == ':':
928 926 p_venv = p_venv[2:]
929 927
930 if any(p_venv in p for p in paths):
931 # Running properly in the virtualenv, don't need to do anything
928 if any(os.fspath(p_venv) in os.fspath(p) for p in paths):
929 # Our exe is inside or has access to the virtualenv, don't need to do anything.
932 930 return
933 931
934 932 warn("Attempting to work in a virtualenv. If you encounter problems, please "
935 933 "install IPython inside the virtualenv.")
936 934 if sys.platform == "win32":
937 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
935 virtual_env = Path(os.environ['VIRTUAL_ENV']).joinpath(
936 'Lib',
937 'site-packages'
938 )
938 939 else:
939 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
940 'python%d.%d' % sys.version_info[:2], 'site-packages')
940 virtual_env = Path(os.environ['VIRTUAL_ENV']).joinpath(
941 'lib',
942 "python{}.{}".format(*sys.version_info[:2]),
943 'site-packages'
944 )
941 945
942 946 import site
943 947 sys.path.insert(0, virtual_env)
General Comments 0
You need to be logged in to leave comments. Login now