microsoft / pyright

Static Type Checker for Python
Other
13.12k stars 1.4k forks source link

`reportArgumentType` incorrectly raised for variable-length arguments #8689

Closed AlonKellner closed 1 month ago

AlonKellner commented 1 month ago

Describe the bug When using variable-length arguments (i.e func(*args) or func(**kwargs)) the inferred type for the arguments is incorrect, therefore raising a reportArgumentType error.

Code or Screenshots

from typing import List

def abc(a: str, b: str, c: str):
    print(a, b, c)

def wrap_args(*args: List[str]):
    abc(*args)

def wrap_kwargs(**kwargs: dict[str, str]):
    abc(**kwargs)

In this example, these are the errors:

temp.py
  temp.py:8:10 - error: Argument of type "List[str]" cannot be assigned to parameter "a" of type "str" in function "abc"
    "List[str]" is incompatible with "str" (reportArgumentType)
  temp.py:8:10 - error: Argument of type "List[str]" cannot be assigned to parameter "b" of type "str" in function "abc"
    "List[str]" is incompatible with "str" (reportArgumentType)
  temp.py:8:10 - error: Argument of type "List[str]" cannot be assigned to parameter "c" of type "str" in function "abc"
    "List[str]" is incompatible with "str" (reportArgumentType)
  temp.py:11:11 - error: Argument of type "dict[str, str]" cannot be assigned to parameter "a" of type "str" in function "abc"
    "dict[str, str]" is incompatible with "str" (reportArgumentType)
  temp.py:11:11 - error: Argument of type "dict[str, str]" cannot be assigned to parameter "b" of type "str" in function "abc"
    "dict[str, str]" is incompatible with "str" (reportArgumentType)
  temp.py:11:11 - error: Argument of type "dict[str, str]" cannot be assigned to parameter "c" of type "str" in function "abc"
    "dict[str, str]" is incompatible with "str" (reportArgumentType)
6 errors, 0 warnings, 0 informations 

Although from the argument types perspective there is nothing wrong here, the issue is that the inferred type set to a is the variable-length args type (List[str]), not the expected expanded type (str).

Summary I am not sure where this problem comes from and I am a little out of my depth here, but if you'll point out possible causes and outline the solution I can help with the PR.

erictraut commented 1 month ago

Pyright's behavior here is correct.

Your parameter annotations should be:

def wrap_args(*args: str):
    abc(*args)

def wrap_kwargs(**kwargs: str):
    abc(**kwargs)

Refer to this section of the typing spec for details.

AlonKellner commented 1 month ago

My bad, thanks :)