Generalize the use of smart import paths

Now a lot more parts of the current scripts path are used as a sys path.
This commit is contained in:
Dave Halter
2018-02-16 12:40:31 +01:00
parent 863fbb3702
commit 6a11b7d89e
3 changed files with 28 additions and 13 deletions

View File

@@ -101,11 +101,13 @@ class Script(object):
sys_path = list(map(force_unicode, sys_path))
# Load the Python grammar of the current interpreter.
project = get_default_project(path or os.getcwd())
project = get_default_project(self.path or os.getcwd())
# TODO deprecate and remove sys_path from the Script API.
if sys_path is not None:
project._sys_path = sys_path
self._evaluator = Evaluator(project, environment=environment, script_path=path)
self._evaluator = Evaluator(
project, environment=environment, script_path=self.path
)
self._project = project
debug.speed('init')
self._module_node, source = self._evaluator.parse_and_get_code(

View File

@@ -16,6 +16,15 @@ _CONTAINS_POTENTIAL_PROJECT = 'setup.py', '.git', '.hg', 'MANIFEST.in'
_SERIALIZER_VERSION = 1
def _remove_duplicates_from_path(path):
used = set()
for p in path:
if p in used:
continue
used.add(p)
yield p
def _force_unicode_list(lst):
return list(map(force_unicode, lst))
@@ -98,15 +107,28 @@ class Project(object):
sys_path = list(self._get_base_sys_path(environment))
if self._smart_sys_path:
suffixed.append(self._path)
if evaluator.script_path is not None:
suffixed += detect_additional_paths(evaluator, evaluator.script_path)
suffixed.append(self._path)
traversed = []
for parent in traverse_parents(evaluator.script_path):
traversed.append(parent)
if parent == self._path:
# Don't go futher than the project path.
break
# AFAIK some libraries have imports like `foo.foo.bar`, which
# leads to the conclusion to by default prefer longer paths
# rather than shorter ones by default.
suffixed += reversed(traversed)
if self._django:
prefixed.append(self._path)
return _force_unicode_list(prefixed) + sys_path + _force_unicode_list(suffixed)
path = _force_unicode_list(prefixed) + sys_path + _force_unicode_list(suffixed)
return list(_remove_duplicates_from_path(path))
def save(self):
data = dict(self.__dict__)

View File

@@ -265,15 +265,6 @@ class Importer(object):
sys_path_mod = self._evaluator.get_sys_path() \
+ sys_path.check_sys_path_modifications(self.module_context)
if self.file_path is not None:
# If you edit e.g. gunicorn, there will be imports like this:
# `from gunicorn import something`. But gunicorn is not in the
# sys.path. Therefore look if gunicorn is a parent directory, #56.
if self.import_path:
for path in sys_path.traverse_parents(self.file_path):
if os.path.basename(path) == self.str_import_path[0]:
sys_path_mod.insert(0, force_unicode(os.path.dirname(path)))
break
# Since we know nothing about the call location of the sys.path,
# it's a possibility that the current directory is the origin of
# the Python execution.