1
0
forked from VimPlug/jedi

Make it possible to use goto_definition on "broken" imports

This commit is contained in:
Dave Halter
2019-03-27 00:39:51 +01:00
parent 993567ca56
commit f4c17e578c
7 changed files with 52 additions and 31 deletions

View File

@@ -290,6 +290,16 @@ class Evaluator(object):
if type_ in ('import_from', 'import_name'):
return imports.infer_import(context, name)
error_node = tree.search_ancestor(name, 'error_node')
if error_node is not None:
first_name = error_node.get_first_leaf().value
if first_name == 'from':
level, names = helpers.parse_dotted_names(
error_node.children,
is_import_from=True
)
return imports.Importer(self, names, context.get_root_context(), level).follow()
return helpers.evaluate_call_of_leaf(context, name)
def goto(self, context, name):

View File

@@ -67,6 +67,7 @@ class SubModuleDictMixin(object):
return names
class ModuleMixin(SubModuleDictMixin):
def get_filters(self, search_global=False, until_position=None, origin_scope=None):
yield MergedFilter(

View File

@@ -239,3 +239,24 @@ def execute_evaluated(context, *value_list):
from jedi.evaluate.base_context import ContextSet
arguments = ValuesArguments([ContextSet([value]) for value in value_list])
return context.evaluator.execute(context, arguments)
def parse_dotted_names(nodes, is_import_from):
level = 0
names = []
for node in nodes[1:]:
if node in ('.', '...'):
if not names:
level += len(node.value)
elif node.type == 'dotted_name':
names += node.children[::2]
elif node.type == 'name':
names.append(node)
elif node == ',':
if not is_import_from:
names = []
else:
# Here if the keyword `import` comes along it stops checking
# for names.
break
return level, names

View File

@@ -239,11 +239,6 @@ class Importer(object):
self._evaluator = evaluator
self.level = level
self.module_context = module_context
try:
self.file_path = module_context.py__file__()
except AttributeError:
# Can be None for certain compiled modules like 'builtins'.
self.file_path = None
self._fixed_sys_path = None
self._inference_possible = True
@@ -316,10 +311,16 @@ class Importer(object):
+ sys_path.check_sys_path_modifications(self.module_context)
)
if self.import_path and self.file_path is not None \
and self._evaluator.environment.version_info.major == 2:
# Python2 uses an old strange way of importing relative imports.
sys_path_mod.append(force_unicode(os.path.dirname(self.file_path)))
if self.import_path:
try:
file_path = self.module_context.py__file__()
except AttributeError:
# Can be None for certain compiled modules like 'builtins'.
file_path = None
else:
if self._evaluator.environment.version_info.major == 2:
# Python2 uses an old strange way of importing relative imports.
sys_path_mod.append(force_unicode(os.path.dirname(file_path)))
return sys_path_mod