diff --git a/jedi/evaluate/compiled/access.py b/jedi/evaluate/compiled/access.py index 97a8dd0b..b9bf5c0c 100644 --- a/jedi/evaluate/compiled/access.py +++ b/jedi/evaluate/compiled/access.py @@ -150,7 +150,7 @@ def load_module(evaluator, path=None, name=None, sys_path=None): __import__(dotted_path) except ImportError: # If a module is "corrupt" or not really a Python module or whatever. - debug.warning('Module %s not importable in path %s.', dotted_path, path) + print_to_stderr('Module %s not importable in path %s.' % (dotted_path, path)) return None except Exception: # Since __import__ pretty much makes code execution possible, just @@ -262,6 +262,9 @@ class DirectObjectAccess(object): def py__bases__(self): return [self._create_access_path(base) for base in self._obj.__bases__] + def py__path__(self): + return self._obj.__path__ + @_force_unicode_decorator def get_repr(self): builtins = 'builtins', '__builtin__' diff --git a/jedi/evaluate/compiled/context.py b/jedi/evaluate/compiled/context.py index a51717f0..2b87e3b1 100644 --- a/jedi/evaluate/compiled/context.py +++ b/jedi/evaluate/compiled/context.py @@ -81,6 +81,10 @@ class CompiledObject(Context): for access in self.access_handle.py__bases__() ) + @CheckAttribute + def py__path__(self): + return self.access_handle.py__path__() + def py__bool__(self): return self.access_handle.py__bool__() diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 872ad1e1..5c72a0cd 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -277,6 +277,7 @@ class Importer(object): def follow(self): if not self.import_path: return NO_CONTEXTS + return self._do_import(self.import_path, self.sys_path_with_modifications()) def _do_import(self, import_path, sys_path): @@ -300,6 +301,14 @@ class Importer(object): # Old style return self._do_import(('flaskext',) + import_path[2:], sys_path) + if import_parts[0] in settings.auto_import_modules: + module = compiled.load_module( + self._evaluator, + name='.'.join(import_parts), + sys_path=sys_path, + ) + return ContextSet(module) + module_name = '.'.join(import_parts) try: return ContextSet(self._evaluator.module_cache.get(module_name)) @@ -464,7 +473,7 @@ class Importer(object): def _load_module(evaluator, path=None, code=None, sys_path=None, - module_name=None, safe_module_name=False): + module_name=None, safe_module_name=False, auto_import=False): try: return evaluator.module_cache.get(module_name) except KeyError: @@ -485,9 +494,8 @@ def _load_module(evaluator, path=None, code=None, sys_path=None, if sys_path is None: sys_path = evaluator.get_sys_path() - dotted_path = path and dotted_from_fs_path(path, sys_path) if path is not None and path.endswith(('.py', '.zip', '.egg')) \ - and dotted_path not in settings.auto_import_modules: + and not auto_import: module_node = evaluator.parse( code=code, path=path, cache=True, diff_cache=True, diff --git a/jedi/settings.py b/jedi/settings.py index f1ae6dbb..436fadfc 100644 --- a/jedi/settings.py +++ b/jedi/settings.py @@ -144,7 +144,8 @@ Check for `isinstance` and other information to infer a type. """ auto_import_modules = [ - 'hashlib', # setattr + 'hashlib', # hashlib is mostly using setattr, which jedi doesn't understand + 'gi', # This third-party repository (GTK stuff) doesn't really work with jedi ] """ Modules that are not analyzed but imported, although they contain Python code. diff --git a/test/test_settings.py b/test/test_settings.py index bbe644e6..4958ca45 100644 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -1,8 +1,19 @@ +import pytest + from jedi import settings from jedi.evaluate.compiled import CompiledContextName -def test_base_auto_import_modules(monkeypatch, Script): +@pytest.fixture() +def auto_import_json(monkeypatch): monkeypatch.setattr(settings, 'auto_import_modules', ['json']) + + +def test_base_auto_import_modules(auto_import_json, Script): loads, = Script('import json; json.loads').goto_definitions() assert isinstance(loads._name, CompiledContextName) + + +def test_auto_import_modules_imports(auto_import_json, Script): + main, = Script('from json import tool; tool.main').goto_definitions() + assert isinstance(main._name, CompiledContextName)