Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,11 @@ def check_argument_types(self, arg_types: List[Type], arg_kinds: List[int],
messages.invalid_keyword_var_arg(arg_type, context)
# Get the type of an individual actual argument (for *args
# and **args this is the item type, not the collection type).
if (isinstance(arg_type, TupleType)
and tuple_counter[0] >= len(arg_type.items)
and arg_kinds[actual] == nodes.ARG_STAR):
# The tuple is exhausted. Continue with further arguments.
continue
actual_type = get_actual_type(arg_type, arg_kinds[actual],
tuple_counter)
check_arg(actual_type, arg_type, arg_kinds[actual],
Expand Down Expand Up @@ -1667,7 +1672,8 @@ def map_actuals_to_formals(caller_kinds: List[int],
map[j].append(i)
else:
break
j += 1
if callee_kinds[j] != nodes.ARG_STAR:
j += 1
else:
# Assume that it is an iterable (if it isn't, there will be
# an error later).
Expand All @@ -1676,6 +1682,8 @@ def map_actuals_to_formals(caller_kinds: List[int],
break
else:
map[j].append(i)
if callee_kinds[j] == nodes.ARG_STAR:
break
j += 1
elif kind == nodes.ARG_NAMED:
name = caller_names[i]
Expand Down
2 changes: 1 addition & 1 deletion mypy/test/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ def repr_failure(self, excinfo):
self.parent._prunetraceback(excinfo)
excrepr = excinfo.getrepr(style='short')

return "data: {}:{}\n{}".format(self.obj.file, self.obj.line, excrepr)
return "data: {}:{}:\n{}".format(self.obj.file, self.obj.line, excrepr)


class DataSuite:
Expand Down
19 changes: 19 additions & 0 deletions test-data/unit/check-varargs.test
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,25 @@ f(*it1)
f(*it2) # E: Argument 1 to "f" has incompatible type *Iterable[str]; expected "int"
[builtins fixtures/for.py]

[case testCallVarargsFunctionWithIterableAndPositional]
# options: fast_parser
from typing import Iterable
it1 = None # type: Iterable[int]
def f(*x: int) -> None: pass
f(*it1, 1, 2)
f(*it1, 1, *it1, 2)
f(*it1, '') # E: Argument 2 to "f" has incompatible type "str"; expected "int"
[builtins fixtures/for.py]

[case testCallVarargsFunctionWithTupleAndPositional]
# options: fast_parser
def f(*x: int) -> None: pass
it1 = (1, 2)
f(*it1, 1, 2)
f(*it1, 1, *it1, 2)
f(*it1, '') # E: Argument 2 to "f" has incompatible type "str"; expected "int"
[builtins fixtures/for.py]


-- Calling varargs function + type inference
-- -----------------------------------------
Expand Down