@@ -758,6 +758,33 @@ def init_displayhook(self):
758758 # the appropriate time.
759759 self .display_trap = DisplayTrap (hook = self .displayhook )
760760
761+ @staticmethod
762+ def get_python_link_paths (p : Path ):
763+ """Gets python paths including symlinks
764+
765+ Examples
766+ --------
767+ In [1]: from IPython.core.interactiveshell import InteractiveShell
768+
769+ In [2]: import sys, pathlib
770+
771+ In [3]: paths = InteractiveShell.get_python_link_paths(pathlib.Path(sys.executable))
772+
773+ In [4]: len(paths) == len(set(paths))
774+ Out[4]: True
775+
776+ In [5]: bool(paths)
777+ Out[5]: True
778+ """
779+ paths = [p ]
780+ while p .is_symlink ():
781+ new_path = Path (os .readlink (p ))
782+ if not new_path .is_absolute ():
783+ new_path = p .parent / new_path
784+ p = new_path
785+ paths .append (p )
786+ return paths
787+
761788 def init_virtualenv (self ):
762789 """Add the current virtualenv to sys.path so the user can import modules from it.
763790 This isn't perfect: it doesn't use the Python interpreter with which the
@@ -783,10 +810,7 @@ def init_virtualenv(self):
783810 # stdlib venv may symlink sys.executable, so we can't use realpath.
784811 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
785812 # So we just check every item in the symlink tree (generally <= 3)
786- paths = [p ]
787- while p .is_symlink ():
788- p = Path (os .readlink (p ))
789- paths .append (p .resolve ())
813+ paths = self .get_python_link_paths (p )
790814
791815 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
792816 if p_venv .parts [1 ] == "cygdrive" :
0 commit comments