From 86071dda542e88cf06d98e30b08d3077a6304fc3 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sun, 1 Dec 2019 00:10:11 +0100 Subject: [PATCH] Use a different sys path for import completions and import type inference Fix tests of the #1451 pull request --- jedi/api/project.py | 6 ++++-- jedi/inference/imports.py | 13 ++++++++----- test/completion/on_import.py | 6 +++++- test/test_inference/test_imports.py | 2 ++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/jedi/api/project.py b/jedi/api/project.py index 6c75cd79..6b76c8dc 100644 --- a/jedi/api/project.py +++ b/jedi/api/project.py @@ -94,7 +94,8 @@ class Project(object): return sys_path @inference_state_as_method_param_cache() - def _get_sys_path(self, inference_state, environment=None, add_parent_paths=True): + def _get_sys_path(self, inference_state, environment=None, + add_parent_paths=True, add_init_paths=False): """ Keep this method private for all users of jedi. However internally this one is used like a public method. @@ -117,7 +118,8 @@ class Project(object): for parent_path in traverse_parents(inference_state.script_path): if not parent_path.startswith(self._path): break - if os.path.isfile(os.path.join(parent_path, "__init__.py")): + if not add_init_paths \ + and os.path.isfile(os.path.join(parent_path, "__init__.py")): continue traversed.append(parent_path) diff --git a/jedi/inference/imports.py b/jedi/inference/imports.py index 0292d45b..e6f359cf 100644 --- a/jedi/inference/imports.py +++ b/jedi/inference/imports.py @@ -272,12 +272,15 @@ class Importer(object): for name in self.import_path ) - def _sys_path_with_modifications(self): + def _sys_path_with_modifications(self, is_completion): if self._fixed_sys_path is not None: return self._fixed_sys_path sys_path_mod = ( - self._inference_state.get_sys_path() + # For import completions we don't want to see init paths, but for + # inference we want to show the user as much as possible. + # See GH #1446. + self._inference_state.get_sys_path(add_init_paths=not is_completion) + sys_path.check_sys_path_modifications(self._module_context) ) @@ -297,7 +300,7 @@ class Importer(object): force_unicode(i.value if isinstance(i, tree.Name) else i) for i in self.import_path ) - sys_path = self._sys_path_with_modifications() + sys_path = self._sys_path_with_modifications(is_completion=False) value_set = [None] for i, name in enumerate(self.import_path): @@ -326,7 +329,7 @@ class Importer(object): for name in self._inference_state.compiled_subprocess.get_builtin_module_names()] if search_path is None: - search_path = self._sys_path_with_modifications() + search_path = self._sys_path_with_modifications(is_completion=True) for name in iter_module_names(self._inference_state, search_path): if in_module is None: @@ -355,7 +358,7 @@ class Importer(object): extname = modname[len('flask_'):] names.append(ImportName(self._module_context, extname)) # Now the old style: ``flaskext.foo`` - for dir in self._sys_path_with_modifications(): + for dir in self._sys_path_with_modifications(is_completion=True): flaskext = os.path.join(dir, 'flaskext') if os.path.isdir(flaskext): names += self._get_module_names([flaskext]) diff --git a/test/completion/on_import.py b/test/completion/on_import.py index 733d741e..203b8b9b 100644 --- a/test/completion/on_import.py +++ b/test/completion/on_import.py @@ -20,8 +20,12 @@ def builtin_test(): #? ['sqlite3'] import sqlite3 -#? ['classes'] +# classes is a local module that has an __init__.py and can therefore not be +# found. test can be found. +#? [] import classes +#? ['test'] +import test #? ['timedelta'] from datetime import timedel diff --git a/test/test_inference/test_imports.py b/test/test_inference/test_imports.py index a79f37eb..6bab3a6e 100644 --- a/test/test_inference/test_imports.py +++ b/test/test_inference/test_imports.py @@ -115,6 +115,8 @@ def test_find_module_not_package_zipped(Script, inference_state, environment): def test_import_not_in_sys_path(Script): """ non-direct imports (not in sys.path) + + This is in the end just a fallback. """ a = Script(path='module.py', line=5).goto_definitions() assert a[0].name == 'int'