Skip to content

Wrong "Too many arguments" errors with tuple unpacking #9710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
torfsen opened this issue Nov 10, 2020 · 4 comments
Open

Wrong "Too many arguments" errors with tuple unpacking #9710

torfsen opened this issue Nov 10, 2020 · 4 comments
Labels
bug mypy got something wrong topic-calls Function calls, *args, **kwargs, defaults

Comments

@torfsen
Copy link

torfsen commented Nov 10, 2020

Bug Report

I'm getting wrong or misleading "Too many arguments" errors when using tuple unpacking in function calls.

To Reproduce

from typing import Tuple

def x(x: int, y: int) -> None:
    print(x, y)

def foo1(t: tuple) -> None:
    x(*t[:1], 1)

def foo2(t: tuple) -> None:
    x(*t[:2])

def foo3(t: Tuple[int]) -> None:
    x(*t[:1], 1)

mypy reports:

$ mypy sandbox.py 
sandbox.py:7: error: Too many arguments for "x"
Found 1 error in 1 file (checked 1 source file)

(Line 7 is the call to x in foo1)

Expected Behavior

The call to x in foo1 will never have too many arguments -- it has either 1 (if t is empty) or 2 (if t is not empty). I would have expected an error regarding the possibility of t being empty (i.e. "Potentially not enough arguments").

Also I think that foo1 and foo2 share the same issues regarding their calls of x, so I would have expected to get the same errors for both of them.

Actual Behavior

The call to x in foo1 is reported, but the call to x in foo2 isn't. Interestingly, fixing the tuple length (as in foo3) seems to fix the issue.

Your Environment

  • Mypy version used: 0.790
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.8.5
  • Operating system and version: Ubuntu 18.04.5
@torfsen torfsen added the bug mypy got something wrong label Nov 10, 2020
@torfsen torfsen changed the title Wrong/misleading "Too many arguments" errors with tuple unpacking Wrong "Too many arguments" errors with tuple unpacking Nov 10, 2020
@MaddyGuthridge
Copy link

This is still an issue for me. Can this get some attention so it can be fixed?

@erictraut
Copy link

The sample above uses tuple with no type arguments. That's a problem because mypy can't determine the intended length of the tuple. If you provide type arguments that specify a tuple length, you can avoid type errors.

For example, in the above sample, foo1 could be changed as follows:

def foo1(t: tuple[Any, int]) -> None:
    x(*t[:1], 1)

Mypy is arguably doing the correct thing here. If you don't like the current behavior, you are welcome to propose a different behavior and submit a PR to implement that behavior.

@MaddyGuthridge
Copy link

This example is pretty clear about the length of its tuples and it still gets errors on both return statements of the second function. It seemed that the if len(index) == n expression wasn't filtering what the tuple could be.

def my_function(a: int, b: int, c: int = 0):
    return a + b + c

def do_thing(index: 'tuple[int, int] | tuple[int]'):
    if len(index) == 1:
        return my_function(*index, 2, 3)
    elif len(index) == 2:
        return my_function(*index, 2)

do_thing((1, ))

@erictraut
Copy link

Yes, this would work if mypy were to add type narrowing support for the len(x) == y pattern. This is tracked in issue #1178.

@JelleZijlstra JelleZijlstra added the topic-calls Function calls, *args, **kwargs, defaults label Mar 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-calls Function calls, *args, **kwargs, defaults
Projects
None yet
Development

No branches or pull requests

4 participants