diff --git a/jedi/evaluate/context/iterable.py b/jedi/evaluate/context/iterable.py index a83b88fe..af170367 100644 --- a/jedi/evaluate/context/iterable.py +++ b/jedi/evaluate/context/iterable.py @@ -294,6 +294,11 @@ class DictComprehension(_DictMixin, ComprehensionMixin, Sequence): def get_mapping_item_contexts(self): return self._dict_keys(), self._dict_values() + def exact_key_items(self): + # NOTE: A smarter thing can probably done here to achieve better + # completions, but at least like this jedi doesn't crash + return [] + class GeneratorComprehension(ComprehensionMixin, GeneratorBase): pass diff --git a/jedi/parser_utils.py b/jedi/parser_utils.py index ea15dff9..3a700a60 100644 --- a/jedi/parser_utils.py +++ b/jedi/parser_utils.py @@ -1,3 +1,4 @@ +import re import textwrap from inspect import cleandoc @@ -158,6 +159,7 @@ def get_call_signature(funcdef, width=72, call_string=None): p = '(' + ''.join(param.get_code() for param in funcdef.get_params()).strip() + ')' else: p = funcdef.children[2].get_code() + p = re.sub(r'\s+', ' ', p) if funcdef.annotation: rtype = " ->" + funcdef.annotation.get_code() else: @@ -187,6 +189,8 @@ def get_doc_with_call_signature(scope_node): doc = clean_scope_docstring(scope_node) if call_signature is None: return doc + if not doc: + return call_signature return '%s\n\n%s' % (call_signature, doc) diff --git a/test/completion/functions.py b/test/completion/functions.py index bc4eb200..585b692b 100644 --- a/test/completion/functions.py +++ b/test/completion/functions.py @@ -319,6 +319,7 @@ exe['c'] a = 'a' exe2 = kwargs_func(**{a:3, 'b':4.0}) + #? int() exe2['a'] #? float() @@ -326,6 +327,19 @@ exe2['b'] #? int() float() exe2['c'] +exe3 = kwargs_func(**{k: v for k, v in [(a, 3), ('b', 4.0)]}) + +# Should resolve to the same as 2 but jedi is not smart enough yet +# Here to make sure it doesn't result in crash though +#? +exe3['a'] + +#? +exe3['b'] + +#? +exe3['c'] + # ----------------- # *args / ** kwargs # ----------------- diff --git a/test/completion/types.py b/test/completion/types.py index f0c4c838..753af6c3 100644 --- a/test/completion/types.py +++ b/test/completion/types.py @@ -138,18 +138,30 @@ set_t2.c # python >= 3.5 d = {'a': 3} +dc = {v: 3 for v in ['a']} #? dict() {**d} +#? dict() +{**dc} + #? str() {**d, "b": "b"}["b"] +#? str() +{**dc, "b": "b"}["b"] + # Should resolve to int() but jedi is not smart enough yet # Here to make sure it doesn't result in crash though #? {**d}["a"] +# Should resolve to int() but jedi is not smart enough yet +# Here to make sure it doesn't result in crash though +#? +{**dc}["a"] + s = {1, 2, 3} #? set() diff --git a/test/test_evaluate/test_docstring.py b/test/test_evaluate/test_docstring.py index 3dfbc7af..8b59ab09 100644 --- a/test/test_evaluate/test_docstring.py +++ b/test/test_evaluate/test_docstring.py @@ -142,6 +142,16 @@ def test_docstring_keyword(Script): assert 'assert' in completions[0].docstring() +def test_docstring_params_formatting(Script): + defs = Script(""" + def func(param1, + param2, + param3): + pass + func""").goto_definitions() + assert defs[0].docstring() == 'func(param1, param2, param3)' + + # ---- Numpy Style Tests --- @pytest.mark.skipif(numpydoc_unavailable, diff --git a/test/test_parso_integration/test_parser_utils.py b/test/test_parso_integration/test_parser_utils.py index 6cfd702b..349e8cb9 100644 --- a/test/test_parso_integration/test_parser_utils.py +++ b/test/test_parso_integration/test_parser_utils.py @@ -85,4 +85,4 @@ def test_get_call_signature(code, call_signature): node = node.children[0] assert parser_utils.get_call_signature(node) == call_signature - assert parser_utils.get_doc_with_call_signature(node) == (call_signature + '\n\n') + assert parser_utils.get_doc_with_call_signature(node) == call_signature