1
0
forked from VimPlug/jedi

Make the completions possible for Interpreter objects

This commit is contained in:
Dave Halter
2019-12-31 14:52:44 +01:00
parent b7a8929905
commit 83ce8b1162
5 changed files with 60 additions and 3 deletions

View File

@@ -54,7 +54,6 @@ def _completions_for_dicts(inference_state, dicts, literal_string, cut_end_quote
for dict_key in sorted(_get_python_keys(dicts), key=lambda x: repr(x)):
dict_key_str = _create_repr_string(literal_string, dict_key)
if dict_key_str.startswith(literal_string):
n = dict_key_str[len(literal_string):-len(cut_end_quote) or None]
name = StringName(inference_state, dict_key_str[:-len(cut_end_quote) or None])
yield Completion(
inference_state,

View File

@@ -417,6 +417,23 @@ class DirectObjectAccess(object):
def get_api_type(self):
return get_api_type(self._obj)
def get_array_type(self):
if isinstance(self._obj, dict):
return 'dict'
return None
def get_key_paths(self):
def iter_partial_keys():
# We could use list(keys()), but that might take a lot more memory.
for (i, k) in enumerate(self._obj.keys()):
# Limit key listing at some point. This is artificial, but this
# way we don't get stalled because of slow completions
if i > 50:
break
yield k
return [self._create_access_path(k) for k in iter_partial_keys()]
def get_access_path_tuples(self):
accesses = [create_access(self._inference_state, o) for o in self._get_objects_path()]
return [(access.py__name__(), access) for access in accesses]

View File

@@ -281,6 +281,16 @@ class CompiledObject(Value):
return CompiledModuleContext(self)
return CompiledContext(self)
@property
def array_type(self):
return self.access_handle.get_array_type()
def get_key_values(self):
return [
create_from_access_path(self.inference_state, k)
for k in self.access_handle.get_key_paths()
]
class CompiledName(AbstractNameDefinition):
def __init__(self, inference_state, parent_context, name):

View File

@@ -342,7 +342,7 @@ def test_dict_keys_completions(Script, added_code, column, expected, skip_pre_py
keywords = {None: 1, False: 2, "a": 3}
''')
line = None
comps = Script(code + added_code, line=line, column=column).completions()
comps = Script(code + added_code).complete(line=line, column=column)
if Ellipsis in expected:
# This means that global completions are part of this, so filter all of
# that out.
@@ -365,4 +365,4 @@ def test_fuzzy_match():
def test_ellipsis_completion(Script):
assert Script('...').completions() == []
assert Script('...').complete() == []

View File

@@ -575,3 +575,34 @@ def test_param_annotation_completion(class_is_findable):
code = 'def CallFoo(x: Foo):\n x.ba'
def_, = jedi.Interpreter(code, [locals()]).complete()
assert def_.name == 'bar'
@pytest.mark.skipif(sys.version_info[0] == 2, reason="Ignore Python 2, because EOL")
@pytest.mark.parametrize(
'code, column, expected', [
('strs[', 5, ["'asdf'", "'fbar'", "'foo'", Ellipsis]),
('strs[]', 5, ["'asdf'", "'fbar'", "'foo'", Ellipsis]),
("strs['", 6, ["asdf'", "fbar'", "foo'"]),
("strs[']", 6, ["asdf'", "fbar'", "foo'"]),
('strs["]', 6, ['asdf"', 'fbar"', 'foo"']),
('mixed[', 6, [r"'a\\sdf'", '1', '1.1', "b'foo'", Ellipsis]),
('mixed[1', 7, ['', '.1']),
('mixed[Non', 9, ['e']),
('implicit[10', None, ['00']),
]
)
def test_dict_completion(code, column, expected):
strs = {'asdf': 1, u"""foo""": 2, r'fbar': 3}
mixed = {1: 2, 1.10: 4, None: 6, r'a\sdf': 8, b'foo': 9}
namespaces = [locals(), {'implicit': {1000: 3}}]
comps = jedi.Interpreter(code, namespaces).complete(column=column)
if Ellipsis in expected:
# This means that global completions are part of this, so filter all of
# that out.
comps = [c for c in comps if not c._name.is_value_name and not c.is_keyword]
expected = [e for e in expected if e is not Ellipsis]
assert [c.complete for c in comps] == expected