mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
Finally make it possible to use auto_import_modules for packages
This means that you can now write 'from gi.repository import Gtk' and Gtk completions work. It also means that other libraries could be used like that for speed or other reasons. Fixes #531
This commit is contained in:
@@ -150,7 +150,7 @@ def load_module(evaluator, path=None, name=None, sys_path=None):
|
|||||||
__import__(dotted_path)
|
__import__(dotted_path)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# If a module is "corrupt" or not really a Python module or whatever.
|
# 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
|
return None
|
||||||
except Exception:
|
except Exception:
|
||||||
# Since __import__ pretty much makes code execution possible, just
|
# Since __import__ pretty much makes code execution possible, just
|
||||||
@@ -262,6 +262,9 @@ class DirectObjectAccess(object):
|
|||||||
def py__bases__(self):
|
def py__bases__(self):
|
||||||
return [self._create_access_path(base) for base in self._obj.__bases__]
|
return [self._create_access_path(base) for base in self._obj.__bases__]
|
||||||
|
|
||||||
|
def py__path__(self):
|
||||||
|
return self._obj.__path__
|
||||||
|
|
||||||
@_force_unicode_decorator
|
@_force_unicode_decorator
|
||||||
def get_repr(self):
|
def get_repr(self):
|
||||||
builtins = 'builtins', '__builtin__'
|
builtins = 'builtins', '__builtin__'
|
||||||
|
|||||||
@@ -81,6 +81,10 @@ class CompiledObject(Context):
|
|||||||
for access in self.access_handle.py__bases__()
|
for access in self.access_handle.py__bases__()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@CheckAttribute
|
||||||
|
def py__path__(self):
|
||||||
|
return self.access_handle.py__path__()
|
||||||
|
|
||||||
def py__bool__(self):
|
def py__bool__(self):
|
||||||
return self.access_handle.py__bool__()
|
return self.access_handle.py__bool__()
|
||||||
|
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ class Importer(object):
|
|||||||
def follow(self):
|
def follow(self):
|
||||||
if not self.import_path:
|
if not self.import_path:
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
|
|
||||||
return self._do_import(self.import_path, self.sys_path_with_modifications())
|
return self._do_import(self.import_path, self.sys_path_with_modifications())
|
||||||
|
|
||||||
def _do_import(self, import_path, sys_path):
|
def _do_import(self, import_path, sys_path):
|
||||||
@@ -300,6 +301,14 @@ class Importer(object):
|
|||||||
# Old style
|
# Old style
|
||||||
return self._do_import(('flaskext',) + import_path[2:], sys_path)
|
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)
|
module_name = '.'.join(import_parts)
|
||||||
try:
|
try:
|
||||||
return ContextSet(self._evaluator.module_cache.get(module_name))
|
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,
|
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:
|
try:
|
||||||
return evaluator.module_cache.get(module_name)
|
return evaluator.module_cache.get(module_name)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -485,9 +494,8 @@ def _load_module(evaluator, path=None, code=None, sys_path=None,
|
|||||||
if sys_path is None:
|
if sys_path is None:
|
||||||
sys_path = evaluator.get_sys_path()
|
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')) \
|
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(
|
module_node = evaluator.parse(
|
||||||
code=code, path=path, cache=True, diff_cache=True,
|
code=code, path=path, cache=True, diff_cache=True,
|
||||||
|
|||||||
@@ -144,7 +144,8 @@ Check for `isinstance` and other information to infer a type.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
auto_import_modules = [
|
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.
|
Modules that are not analyzed but imported, although they contain Python code.
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi.evaluate.compiled import CompiledContextName
|
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'])
|
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()
|
loads, = Script('import json; json.loads').goto_definitions()
|
||||||
assert isinstance(loads._name, CompiledContextName)
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user