Fix: no longer shows folders recursively to root

In the previous implementation, Jedi would's traverse_parents function
traversed parent directories to the system root every time. This would
inadvertently add every folder to the system root every time. Obviously,
this is not the behavior desired for the import system.

This pull request provides a new argument to the traverse_parents
function, "root", which represents the root parent for the search. This
argument defaults to None, thereby preserving the existing behavior of
the function.

I chose to duplicate some code for performance reasons. Since I'm trying
to avoid too much path manipulation magic, we do:

* a search to a valid specified root, OR
* a simple upward search until hitting the system root when there is no
valid root specified.
This commit is contained in:
Sam Roeca
2019-11-28 23:04:08 -05:00
parent 761f0828c7
commit 03b4177d3d
2 changed files with 25 additions and 6 deletions

View File

@@ -110,7 +110,10 @@ class Project(object):
suffixed += discover_buildout_paths(inference_state, inference_state.script_path)
if add_parent_paths:
traversed = list(traverse_parents(inference_state.script_path))
traversed = list(traverse_parents(
inference_state.script_path,
root=self._path,
))
# AFAIK some libraries have imports like `foo.foo.bar`, which
# leads to the conclusion to by default prefer longer paths

View File

@@ -2,15 +2,31 @@ import os
from contextlib import contextmanager
def traverse_parents(path, include_current=False):
def traverse_parents(path, root=None, include_current=False):
"""Iterate directories from a path to search root
:path: the path of the script/directory to check.
:root: the root of the upward search. Assumes the system root if root is
None.
:include_current: includes the current file / directory.
If the root path is not a substring of the provided path, assume the root
search path as well.
"""
if not include_current:
path = os.path.dirname(path)
previous = None
while previous != path:
yield path
previous = path
path = os.path.dirname(path)
if root is None or not path.startswith(root):
while previous != path:
yield path
previous = path
path = os.path.dirname(path)
else:
while previous != root:
yield path
previous = path
path = os.path.dirname(path)
@contextmanager