Open ilevkivskyi opened 7 years ago
Related observations: this passes
y: List[Tuple[int]]
reveal_type(list(*y)) # Revealed type is 'builtins.list[builtins.int*]'
but fails at runtime with:
TypeError: list() takes at most 1 argument (2 given)
and similar for set etc. It looks like this is a general bug with star types.
There may be a few edge cases left here, but in general mypy doesn't know enough about star types to tell its length (Tuple[]
excepted), and it will let it through if there is a possible length for which the call would succeed. So for your second example, the type of y
is List
of some unspecified length, so list(*y)
passes because if y were to have length 1 the call would succeed. (BTW your second example doesn't show the initialization for y
so I'd expect NameError
at runtime, so I really have to side with mypy here. :-)
Regarding the first case (zip(*y)
) things are a little subtler, since zip()
has many overloads for different argument counts. It appears here mypy finds the call compatible with all of the overloads (due to the above strategy related to star), tries to return something like the join of the return types, and comes up with Any
. IITC that join is what it generally does when multiple overloads apply, but in other cases there is probably a better reason for it.
I'm not sure what to do for star-args with overloaded functions -- the "join" behavior seems reasonable enough to me in cases where the join is reasonable, e.g.:
from typing import TypeVar, overload, List
T = TypeVar('T')
@overload
def zap(a: T) -> T: pass
@overload
def zap(a: T, b: T, c: T, *more: T) -> T: pass
def zap(*args): pass
a: List[int]
reveal_type(zap(*a)) # int
b: float
reveal_type(zap(b, *a)) # float
I'm not sure what to do for star-args with overloaded functions -- the "join" behavior seems reasonable enough to me in cases where the join is reasonable
I think join
should never return plain Any
(unless maybe in situation where one of joining types is Any
, but this is a separate discussion https://github.com/python/mypy/issues/3194), so that I would just "tighten" the join
.
Is this the rigvt tissue for that?
I didn't find any other issue for this, so I propose to track this here.
This seems pretty similar to #1322. Also, #3256 is related.
This appears to be fixed. The revealed type in the original post is now builtins.zip[builtins.tuple[Any, ...]]
. That's better than the original Any
. For comparison, pyright reveals zip[tuple[int]]
which is more accurate.
I think this is a bug since we should never silently infer
Any
from a precisely typed call.