Tests and fixes for keyword completions

This commit is contained in:
Dave Halter
2019-05-29 01:26:38 +02:00
parent 4b3262622b
commit 0e5b17be85
4 changed files with 52 additions and 1 deletions

View File

@@ -4,6 +4,7 @@ These classes are the much bigger part of the whole API, because they contain
the interesting information about completion and goto operations.
"""
import re
import warnings
from parso.python.tree import search_ancestor
@@ -314,9 +315,14 @@ class BaseDefinition(object):
return '.'.join(path if path[0] else path[1:])
def is_stub(self):
if not self._name.is_context_name:
return False
return all(c.is_stub() for c in self._name.infer())
def goto_stubs(self):
if not self._name.is_context_name:
return []
if self.is_stub():
return [self]
@@ -326,10 +332,16 @@ class BaseDefinition(object):
]
def goto_assignments(self):
if not self._name.is_context_name:
return []
return [self if n == self._name else Definition(self._evaluator, n)
for n in self._name.goto()]
def infer(self):
if not self._name.is_context_name:
return []
tree_name = self._name.tree_name
parent_context = self._name.parent_context
# Param names are special because they are not handled by
@@ -368,6 +380,9 @@ class BaseDefinition(object):
raise AttributeError('There are no params defined on this.')
def parent(self):
if not self._name.is_context_name:
return None
context = self._name.parent_context
if context is None:
return None
@@ -393,7 +408,7 @@ class BaseDefinition(object):
:return str: Returns the line(s) of code or an empty string if it's a
builtin.
"""
if self.in_builtin_module():
if not self._name.is_context_name or self.in_builtin_module():
return ''
lines = self._name.get_root_context().code_lines
@@ -491,6 +506,8 @@ class Completion(BaseDefinition):
@memoize_method
def follow_definition(self):
"""
Deprecated!
Return the original definitions. I strongly recommend not using it for
your completions, because it might slow down |jedi|. If you want to
read only a few objects (<=20), it might be useful, especially to get
@@ -498,6 +515,14 @@ class Completion(BaseDefinition):
follows all results. This means with 1000 completions (e.g. numpy),
it's just PITA-slow.
"""
warnings.warn(
"Deprecated since version 0.14.0. Use .infer.",
DeprecationWarning,
stacklevel=2
)
if not self._name.is_context_name:
return []
defs = self._name.infer()
return [Definition(self._evaluator, d.name) for d in defs]

View File

@@ -21,6 +21,7 @@ def get_operator(evaluator, string, pos):
class KeywordName(AbstractNameDefinition):
api_type = u'keyword'
is_context_name = False
def __init__(self, evaluator, name):
self.evaluator = evaluator

View File

@@ -12,6 +12,10 @@ class AbstractNameDefinition(object):
string_name = None
parent_context = None
tree_name = None
is_context_name = True
"""
Used for the Jedi API to know if it's a keyword or an actual name.
"""
@abstractmethod
def infer(self):

View File

@@ -25,3 +25,24 @@ def test_keyword(Script, environment):
completions = Script("import", 1, 1).completions()
assert len(completions) > 10 and 'if' in [c.name for c in completions]
assert Script("assert").goto_definitions() == []
def test_keyword_attributes(Script):
def_, = Script('def').completions()
assert def_.name == 'def'
assert def_.complete == ''
assert def_.is_keyword is True
assert def_.is_stub() is False
assert def_.goto_stubs() == []
assert def_.goto_assignments() == []
assert def_.infer() == []
assert def_.parent() is None
assert def_.docstring()
assert def_.description == 'keyword def'
assert def_.get_line_code() == ''
assert def_.full_name == 'def'
assert def_.line is def_.column is None
assert def_.in_builtin_module() is True
assert def_.module_name in ('builtins', '__builtin__')
assert 'typeshed' in def_.module_path
assert def_.type == 'keyword'