From 0703a69369b8605b2eb417cd764b6d1e7eb5a271 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 26 Jul 2019 12:11:45 +0200 Subject: [PATCH] Some progress in signature understanding --- jedi/evaluate/signature.py | 17 +++++++++++------ test/test_evaluate/test_signature.py | 11 +++++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/jedi/evaluate/signature.py b/jedi/evaluate/signature.py index 2e215af8..55d50527 100644 --- a/jedi/evaluate/signature.py +++ b/jedi/evaluate/signature.py @@ -148,12 +148,15 @@ def _iter_nodes_for_param(param_name, star_count): trailer=trailer, ) for c in contexts: - yield _remove_given_params(args, c.get_param_names(), star_count) + yield _process_params( + _remove_given_params(args, c.get_param_names()), + star_count, + ) else: assert False -def _remove_given_params(arguments, param_names, star_count): +def _remove_given_params(arguments, param_names): count = 0 used_keys = set() for key, _ in arguments.unpack(): @@ -163,14 +166,16 @@ def _remove_given_params(arguments, param_names, star_count): used_keys.add(key) for p in param_names: - kind = p.get_kind() - if count and kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.POSITIONAL_ONLY): + if count and p.maybe_positional_argument(): count -= 1 continue - if p.string_name in used_keys \ - and kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY): + if p.string_name in used_keys and p.maybe_keyword_argument(): continue + yield p + +def _process_params(param_names, star_count): + for p in param_names: # TODO recurse on *args/**kwargs if star_count == 1 and p.maybe_positional_argument(): yield ParamNameFixedKind(p, Parameter.POSITIONAL_ONLY) diff --git a/test/test_evaluate/test_signature.py b/test/test_evaluate/test_signature.py index 946b5929..7e20fd58 100644 --- a/test/test_evaluate/test_signature.py +++ b/test/test_evaluate/test_signature.py @@ -98,6 +98,12 @@ def test_tree_signature(Script, environment, code, expected): ('combined_redirect(simple, simple3)', 'a, b, /, *, a, x: int'), ('combined_redirect(simple2, simple)', 'x, /, *, a, b, c'), ('combined_redirect(simple3, simple)', 'a, x: int, /, *, a, b, c'), + + ('combined_redirect(simple, kw)', 'a, b, /, *, a, b, c, **kwargs'), + ('combined_redirect(kw, simple)', 'a, b, /, *, a, b, c, **kwargs'), + + ('combined_lot_of_args(kw, simple4)', '*, b'), + ('combined_lot_of_args(simple4, kw)', '*, b, c'), ] ) def test_nested_signatures(Script, environment, combination, expected): @@ -105,6 +111,7 @@ def test_nested_signatures(Script, environment, combination, expected): def simple(a, b, *, c): ... def simple2(x): ... def simple3(a, x: int): ... + def simple4(a, b, x: int): ... def a(a, b, *args): ... def kw(a, b, *, c, **kwargs): ... def akw(a, b, *args, **kwargs): ... @@ -113,10 +120,10 @@ def test_nested_signatures(Script, environment, combination, expected): return lambda *args, **kwargs: func(1) def full_redirect(func): return lambda *args, **kwargs: func(1, *args, **kwargs) - def full_redirect(func): - return lambda *args, **kwargs: func(, *args, **kwargs) def combined_redirect(func1, func2): return lambda *args, **kwargs: func1(*args) + func2(**kwargs) + def combined_lot_of_args(func1, func2): + return lambda *args, **kwargs: func1(1, 2, 3, 4, *args) + func2(a=3, x=1, y=1, **kwargs) ''') code += 'z = ' + combination + '\nz(' sig, = Script(code).call_signatures()