From 259b90d7b4e42b10ccf3d223f82210f366ab1603 Mon Sep 17 00:00:00 2001 From: Ekin Dursun Date: Mon, 26 Aug 2019 16:22:16 +0300 Subject: [PATCH 1/4] Accept empty list unpacking for function without parameter --- mypy/checkexpr.py | 6 +++--- test-data/unit/check-varargs.test | 12 ++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 135f796d479e..4c0f3c1a4c6f 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1233,7 +1233,7 @@ def check_for_extra_actual_arguments(self, for i, kind in enumerate(actual_kinds): if i not in all_actuals and ( kind != nodes.ARG_STAR or - not is_empty_tuple(actual_types[i])): + is_not_empty_tuple(actual_types[i])): # Extra actual: not matched by a formal argument. ok = False if kind != nodes.ARG_NAMED: @@ -3833,9 +3833,9 @@ def is_async_def(t: Type) -> bool: return isinstance(t, Instance) and t.type.fullname() == 'typing.Coroutine' -def is_empty_tuple(t: Type) -> bool: +def is_not_empty_tuple(t: Type) -> bool: t = get_proper_type(t) - return isinstance(t, TupleType) and not t.items + return isinstance(t, TupleType) and bool(t.items) def is_duplicate_mapping(mapping: List[int], actual_kinds: List[int]) -> bool: diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test index ceca1fe57c94..7c22980ec582 100644 --- a/test-data/unit/check-varargs.test +++ b/test-data/unit/check-varargs.test @@ -353,7 +353,7 @@ class CC(C): pass from typing import Any d, a = None, None # type: (Any, A) f(a, a, *d) # Fail -f(a, *d) # Fail +f(a, *d) # Ok f(*d) # Ok g(*d) @@ -366,7 +366,6 @@ class A: pass [builtins fixtures/list.pyi] [out] main:3: error: Too many arguments for "f" -main:4: error: Too many arguments for "f" [case testListVarArgsAndSubtyping] from typing import List @@ -448,6 +447,15 @@ def f(x: int, *, y: str) -> None: pass f(y='x', *(1,)) [builtins fixtures/list.pyi] +[case testVarArgsEmptyList] +from typing import List + +def foo() -> None: + pass + +lst: List[int] = [] +foo(*lst) +[builtins fixtures/list.pyi] -- Overloads + varargs -- ------------------- From f1afa29fe5b8b71edc0a2a8a20dc2ce955f01686 Mon Sep 17 00:00:00 2001 From: Ekin Dursun Date: Tue, 27 Aug 2019 10:52:09 +0300 Subject: [PATCH 2/4] Update ambiguous name --- mypy/checkexpr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 4c0f3c1a4c6f..c2e780e44f71 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1233,7 +1233,7 @@ def check_for_extra_actual_arguments(self, for i, kind in enumerate(actual_kinds): if i not in all_actuals and ( kind != nodes.ARG_STAR or - is_not_empty_tuple(actual_types[i])): + is_non_empty_tuple(actual_types[i])): # Extra actual: not matched by a formal argument. ok = False if kind != nodes.ARG_NAMED: @@ -3833,7 +3833,7 @@ def is_async_def(t: Type) -> bool: return isinstance(t, Instance) and t.type.fullname() == 'typing.Coroutine' -def is_not_empty_tuple(t: Type) -> bool: +def is_non_empty_tuple(t: Type) -> bool: t = get_proper_type(t) return isinstance(t, TupleType) and bool(t.items) From 7689689865d78fcf849ba418667861cddf119be5 Mon Sep 17 00:00:00 2001 From: Ekin Dursun Date: Tue, 27 Aug 2019 10:56:56 +0300 Subject: [PATCH 3/4] Add clarifying comment --- mypy/checkexpr.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index c2e780e44f71..25db339d63dc 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1233,6 +1233,8 @@ def check_for_extra_actual_arguments(self, for i, kind in enumerate(actual_kinds): if i not in all_actuals and ( kind != nodes.ARG_STAR or + # We accept the other iterables than tuple (including Any) + # as star arguments because they could be empty, resulting no arguments. is_non_empty_tuple(actual_types[i])): # Extra actual: not matched by a formal argument. ok = False From 3bec06ffa15723c0fc799d3df439647644e5c613 Mon Sep 17 00:00:00 2001 From: Ekin Dursun Date: Tue, 27 Aug 2019 20:35:39 +0300 Subject: [PATCH 4/4] Add test for empty tuple --- test-data/unit/check-varargs.test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test index 7c22980ec582..78de84173ae4 100644 --- a/test-data/unit/check-varargs.test +++ b/test-data/unit/check-varargs.test @@ -457,6 +457,12 @@ lst: List[int] = [] foo(*lst) [builtins fixtures/list.pyi] +[case testVarArgsEmptyTuple] +def foo() -> None: + pass + +foo(*()) + -- Overloads + varargs -- -------------------