From da607ae87a8dc356c91be3b8e4f237750a6ba707 2022-03-03 10:37:21 From: Matthias Bussonnier Date: 2022-03-03 10:37:21 Subject: [PATCH] Merge pull request #13559 from bucknerns/fix_path_loop_with_tests Fix for the path loop that's compatible with python 3.8 --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 6b30a22..93c234f 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -758,6 +758,33 @@ class InteractiveShell(SingletonConfigurable): # the appropriate time. self.display_trap = DisplayTrap(hook=self.displayhook) + @staticmethod + def get_path_links(p: Path): + """Gets path links including all symlinks + + Examples + -------- + In [1]: from IPython.core.interactiveshell import InteractiveShell + + In [2]: import sys, pathlib + + In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable)) + + In [4]: len(paths) == len(set(paths)) + Out[4]: True + + In [5]: bool(paths) + Out[5]: True + """ + paths = [p] + while p.is_symlink(): + new_path = Path(os.readlink(p)) + if not new_path.is_absolute(): + new_path = p.parent / new_path + p = new_path + paths.append(p) + return paths + def init_virtualenv(self): """Add the current virtualenv to sys.path so the user can import modules from it. This isn't perfect: it doesn't use the Python interpreter with which the @@ -783,10 +810,7 @@ class InteractiveShell(SingletonConfigurable): # stdlib venv may symlink sys.executable, so we can't use realpath. # but others can symlink *to* the venv Python, so we can't just use sys.executable. # So we just check every item in the symlink tree (generally <= 3) - paths = [p] - while p.is_symlink(): - p = Path(os.readlink(p)) - paths.append(p.resolve()) + paths = self.get_path_links(p) # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible if p_venv.parts[1] == "cygdrive":