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()
|
self.reset_recursion_limitations()
|
||||||
|
|
||||||
def import_module(self, import_names, parent_module_value=None,
|
def import_module(self, import_names, sys_path=None, prefer_stubs=True):
|
||||||
sys_path=None, prefer_stubs=True):
|
return imports.import_module_by_names(
|
||||||
if sys_path is None:
|
self, import_names, sys_path, prefer_stubs=prefer_stubs)
|
||||||
sys_path = self.get_sys_path()
|
|
||||||
return imports.import_module(self, import_names, parent_module_value,
|
|
||||||
sys_path, prefer_stubs=prefer_stubs)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@plugin_manager.decorate()
|
@plugin_manager.decorate()
|
||||||
|
|||||||
@@ -391,15 +391,16 @@ class DirectObjectAccess(object):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
try:
|
if module is not None:
|
||||||
__import__(module)
|
try:
|
||||||
# For some modules like _sqlite3, the __module__ for classes is
|
__import__(module)
|
||||||
# different, in this case it's sqlite3. So we have to try to
|
# For some modules like _sqlite3, the __module__ for classes is
|
||||||
# load that "original" module, because it's not loaded yet. If
|
# different, in this case it's sqlite3. So we have to try to
|
||||||
# we don't do that, we don't really have a "parent" module and
|
# load that "original" module, because it's not loaded yet. If
|
||||||
# we would fall back to builtins.
|
# we don't do that, we don't really have a "parent" module and
|
||||||
except ImportError:
|
# we would fall back to builtins.
|
||||||
pass
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
module = inspect.getmodule(return_obj)
|
module = inspect.getmodule(return_obj)
|
||||||
if module is None:
|
if module is None:
|
||||||
|
|||||||
@@ -288,26 +288,11 @@ class Importer(object):
|
|||||||
if not self.import_path or not self._infer_possible:
|
if not self.import_path or not self._infer_possible:
|
||||||
return NO_VALUES
|
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)
|
sys_path = self._sys_path_with_modifications(is_completion=False)
|
||||||
|
|
||||||
value_set = [None]
|
return import_module_by_names(
|
||||||
for i, name in enumerate(self.import_path):
|
self._inference_state, self.import_path, sys_path, self._module_context
|
||||||
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
|
|
||||||
|
|
||||||
def _get_module_names(self, search_path=None, in_module=None):
|
def _get_module_names(self, search_path=None, in_module=None):
|
||||||
"""
|
"""
|
||||||
@@ -381,6 +366,36 @@ class Importer(object):
|
|||||||
return names
|
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()
|
@plugin_manager.decorate()
|
||||||
@import_module_decorator
|
@import_module_decorator
|
||||||
def import_module(inference_state, import_names, parent_module_value, sys_path):
|
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)
|
d, = script1.goto_definitions(only_stubs=True)
|
||||||
assert d.is_stub()
|
assert d.is_stub()
|
||||||
assert d.full_name == 'sqlite3.dbapi2.Connection'
|
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}],
|
{'goto_has_python': True}],
|
||||||
|
|
||||||
['from keyword import kwlist; kwlist', 'typing.Sequence', True, 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,
|
['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,
|
['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, {}],
|
['from socket import socket', 'socket.socket', True, True, {}],
|
||||||
|
|
||||||
['import with_stub', 'with_stub', True, True, {}],
|
['import with_stub', 'with_stub', True, True, {}],
|
||||||
|
|||||||
Reference in New Issue
Block a user