Implement goto_assignments(follow_imports=True). Fixes #382.

This commit is contained in:
Dave Halter
2016-08-03 18:05:08 +02:00
parent c1bef454f5
commit ebd080a0fd
4 changed files with 37 additions and 7 deletions

View File

@@ -196,7 +196,7 @@ class Script(object):
# the API.
return helpers.sorted_definitions(set(defs))
def goto_assignments(self):
def goto_assignments(self, follow_imports=False):
"""
Return the first definition found. Imports and statements aren't
followed. Multiple objects may be returned, because Python itself is a
@@ -205,9 +205,22 @@ class Script(object):
:rtype: list of :class:`classes.Definition`
"""
results = self._goto()
d = [classes.Definition(self._evaluator, d) for d in set(results)]
return helpers.sorted_definitions(d)
def filter_follow_imports(names):
for name in names:
definition = name.get_definition()
if definition.type in ('import_name', 'import_from'):
imp = imports.ImportWrapper(self._evaluator, name)
for name in filter_follow_imports(imp.follow(is_goto=True)):
yield name
else:
yield name
names = self._goto()
if follow_imports:
names = filter_follow_imports(names)
defs = [classes.Definition(self._evaluator, d) for d in set(names)]
return helpers.sorted_definitions(defs)
def _goto(self):
"""

View File

@@ -118,7 +118,11 @@ class TestCase(object):
try:
with open(self.path) as f:
self.script = jedi.Script(f.read(), self.line, self.column, self.path)
self.objects = getattr(self.script, self.operation)()
kwargs = {}
if self.operation == 'goto_assignments':
kwargs['follow_imports'] = random.choice([False, True])
self.objects = getattr(self.script, self.operation)(**kwargs)
if print_result:
print("{path}: Line {line} column {column}".format(**self.__dict__))
self.show_location(self.line, self.column)

View File

@@ -164,3 +164,16 @@ def test_get_line_code():
assert get_line_code(source, line=2) == line
assert get_line_code(source, line=2, after=1) == line + '\nother_line'
assert get_line_code(source, line=2, after=1, before=1) == source
def test_goto_assignments_follow_imports():
code = dedent("""
import inspect
inspect.isfunction""")
definition, = api.Script(code, column=0).goto_assignments(follow_imports=True)
assert 'inspect.py' in definition.module_path
assert definition.start_pos == (1, 0)
definition, = api.Script(code).goto_assignments(follow_imports=True)
assert 'inspect.py' in definition.module_path
assert definition.start_pos > (1, 0)

View File

@@ -153,8 +153,8 @@ class TestInterpreterAPI(TestCase):
def foo(bar):
pass
lambd = lambda x: 3
lambd = lambda xyz: 3
self.check_interpreter_complete('foo(bar', locals(), ['bar'])
# TODO we're not yet using the Python3.5 inspect.signature, yet.
assert not jedi.Interpreter('lambd(x', [locals()]).completions()
assert not jedi.Interpreter('lambd(xyz', [locals()]).completions()