`tuple` instantiation ignores generics
a = [1,2]
b: tuple[int, int] = tuple[int, int](a) # Incompatible types in assignment (expression has type "Tuple[int, ...]", variable has type "Tuple[int, int]") [assignment]
related: #15171
um, I don't think there is a bug here? python list type is always variable length (https://docs.python.org/3/library/typing.html#annotating-tuples, not sure if there's a better reference)... in terms of the typing, the OP code is equivalent:
def f() -> list[int]: result = [] result.append(1) result.append(2) return result
b = tupleint, int
... and as a type checker I cannot tell how many elements are in f() so cannot guarantee that the b = line is correct.
For what it's worth, I think the only way to initialise a tuple[int, int] is to give it something that is guaranteed to have 2 elements; only tuple can give that guarantee. So you can write b = tuple[int, int]( (1, 2) ) for example.
i don't remember raising this, but i think the confustion comes from the fact that mypy is special casing tuple. its definition in typeshed looks like this:
class tuple(Sequence[_T_co]):
def __new__(cls, iterable: Iterable[_T_co] = ..., /) -> Self: ...
which normally would mean it only cares about the type inside the iterable, not its length, as eric traut said in https://github.com/python/mypy/issues/15171#issuecomment-1677919260.
The issue is that:
a: list[int]
b = tuple[int, int](a)
reveal_type(b) # builtins.tuple[builtins.int, ...]
The inferred type is NOT based on what was denoted(tuple[int, int]), instead being based on some special casing behavior.
Here is a better example:
a: list[str]
b = tuple[int, int](a)
reveal_type(b) # builtins.tuple[builtins.str, ...]
c = list[int](a)
reveal_type(c) # builtins.list[builtins.int, ...]
list is handled correctly, tuple is special cased and incorrect.
yep, sorry, misinterpreted the OP - thanks for the clarifications
current master (10f18a82b612b6127659cd64aa60c10b9cc7a904) I think gives (on the better example):
/home/xju/tmp/xxx.py:2:21: error: Argument 1 to "tuple" has incompatible type "list[str]"; expected "tuple[int, int]" [arg-type] /home/xju/tmp/xxx.py:3:13: note: Revealed type is "tuple[builtins.int, builtins.int]" /home/xju/tmp/xxx.py:5:15: error: Argument 1 to "list" has incompatible type "list[str]"; expected "Iterable[int]" [arg-type] /home/xju/tmp/xxx.py:6:13: note: Revealed type is "builtins.list[builtins.int]" Found 2 errors in 1 file (checked 1 source file)
... is that more like it?