mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Fix a goto case with nested pyi files
This commit is contained in:
@@ -107,12 +107,9 @@ class InferenceState(object):
|
||||
|
||||
self.reset_recursion_limitations()
|
||||
|
||||
def import_module(self, import_names, parent_module_value=None,
|
||||
sys_path=None, prefer_stubs=True):
|
||||
if sys_path is None:
|
||||
sys_path = self.get_sys_path()
|
||||
return imports.import_module(self, import_names, parent_module_value,
|
||||
sys_path, prefer_stubs=prefer_stubs)
|
||||
def import_module(self, import_names, sys_path=None, prefer_stubs=True):
|
||||
return imports.import_module_by_names(
|
||||
self, import_names, sys_path, prefer_stubs=prefer_stubs)
|
||||
|
||||
@staticmethod
|
||||
@plugin_manager.decorate()
|
||||
|
||||
@@ -391,15 +391,16 @@ class DirectObjectAccess(object):
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
__import__(module)
|
||||
# For some modules like _sqlite3, the __module__ for classes is
|
||||
# different, in this case it's sqlite3. So we have to try to
|
||||
# load that "original" module, because it's not loaded yet. If
|
||||
# we don't do that, we don't really have a "parent" module and
|
||||
# we would fall back to builtins.
|
||||
except ImportError:
|
||||
pass
|
||||
if module is not None:
|
||||
try:
|
||||
__import__(module)
|
||||
# For some modules like _sqlite3, the __module__ for classes is
|
||||
# different, in this case it's sqlite3. So we have to try to
|
||||
# load that "original" module, because it's not loaded yet. If
|
||||
# we don't do that, we don't really have a "parent" module and
|
||||
# we would fall back to builtins.
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
module = inspect.getmodule(return_obj)
|
||||
if module is None:
|
||||
|
||||
@@ -288,26 +288,11 @@ class Importer(object):
|
||||
if not self.import_path or not self._infer_possible:
|
||||
return NO_VALUES
|
||||
|
||||
import_names = tuple(
|
||||
force_unicode(i.value if isinstance(i, tree.Name) else i)
|
||||
for i in self.import_path
|
||||
)
|
||||
sys_path = self._sys_path_with_modifications(is_completion=False)
|
||||
|
||||
value_set = [None]
|
||||
for i, name in enumerate(self.import_path):
|
||||
value_set = ValueSet.from_sets([
|
||||
self._inference_state.import_module(
|
||||
import_names[:i+1],
|
||||
parent_module_value,
|
||||
sys_path
|
||||
) for parent_module_value in value_set
|
||||
])
|
||||
if not value_set:
|
||||
message = 'No module named ' + '.'.join(import_names)
|
||||
_add_error(self._module_context, name, message)
|
||||
return NO_VALUES
|
||||
return value_set
|
||||
return import_module_by_names(
|
||||
self._inference_state, self.import_path, sys_path, self._module_context
|
||||
)
|
||||
|
||||
def _get_module_names(self, search_path=None, in_module=None):
|
||||
"""
|
||||
@@ -381,6 +366,36 @@ class Importer(object):
|
||||
return names
|
||||
|
||||
|
||||
def import_module_by_names(inference_state, import_names, sys_path=None,
|
||||
module_context=None, prefer_stubs=True):
|
||||
if sys_path is None:
|
||||
sys_path = inference_state.get_sys_path()
|
||||
|
||||
str_import_names = tuple(
|
||||
force_unicode(i.value if isinstance(i, tree.Name) else i)
|
||||
for i in import_names
|
||||
)
|
||||
value_set = [None]
|
||||
for i, name in enumerate(import_names):
|
||||
value_set = ValueSet.from_sets([
|
||||
import_module(
|
||||
inference_state,
|
||||
str_import_names[:i+1],
|
||||
parent_module_value,
|
||||
sys_path,
|
||||
prefer_stubs=prefer_stubs,
|
||||
) for parent_module_value in value_set
|
||||
])
|
||||
if not value_set:
|
||||
message = 'No module named ' + '.'.join(str_import_names)
|
||||
if module_context is not None:
|
||||
_add_error(module_context, name, message)
|
||||
else:
|
||||
debug.warning(message)
|
||||
return NO_VALUES
|
||||
return value_set
|
||||
|
||||
|
||||
@plugin_manager.decorate()
|
||||
@import_module_decorator
|
||||
def import_module(inference_state, import_names, parent_module_value, sys_path):
|
||||
|
||||
@@ -14,3 +14,10 @@ def test_sqlite3_conversion(Script):
|
||||
d, = script1.goto_definitions(only_stubs=True)
|
||||
assert d.is_stub()
|
||||
assert d.full_name == 'sqlite3.dbapi2.Connection'
|
||||
|
||||
script2 = Script(path=d.module_path, line=d.line, column=d.column)
|
||||
d, = script2.goto_definitions()
|
||||
assert not d.is_stub()
|
||||
assert d.full_name == 'sqlite3.Connection'
|
||||
v, = d._name.infer()
|
||||
assert v.is_compiled()
|
||||
|
||||
@@ -28,12 +28,12 @@ from test.helpers import root_dir
|
||||
{'goto_has_python': True}],
|
||||
|
||||
['from keyword import kwlist; kwlist', 'typing.Sequence', True, True,
|
||||
{'full_name': 'keyword.kwlist'}],
|
||||
{'goto_full_name': 'keyword.kwlist'}],
|
||||
['from keyword import kwlist', 'typing.Sequence', True, True,
|
||||
{'full_name': 'keyword.kwlist'}],
|
||||
{'goto_full_name': 'keyword.kwlist'}],
|
||||
|
||||
['from socket import AF_INET', 'socket.AddressFamily', True, False,
|
||||
{'full_name': 'socket.AF_INET'}],
|
||||
{'goto_full_name': 'socket.AF_INET'}],
|
||||
['from socket import socket', 'socket.socket', True, True, {}],
|
||||
|
||||
['import with_stub', 'with_stub', True, True, {}],
|
||||
|
||||
Reference in New Issue
Block a user