You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Empty collection's subtype evaluates to Unknown when in tuple passed to Iterable with TypeVar parameter #4244
Describe the bug
An empty set or list inside a tuple used as a function parameter typed as Iterable[_T] (where _T is a TypeVar) will result in reportUnknownArgumentType. This does not happen inside of lists. And does not happen if the empty collection is a tuple (likely because zero-length tuples are their own type). It also only happens with TypeVar.
I think pyright is correct to report an "unknown argument type" for the expressions assigned to b5 and b6, so I don't consider that a bug.
However, I agree that there is an inconsistency here. The expressions b2 and b3 should also generate the same error because they also include an "unknown" type argument. This is a bug.
Calls to foo will not generate the same error because bidirectional type inference causes [] to be inferred as Iterable[Any] rather than list[Unknown]. Similarly, {} is inferred as Iterable[Any] rather than dict[Unknown, Unknown].
The expression () always evaluates to tuple[()] and is interpreted as Iterable[Any], so that will never trigger the "unknown" checks.
Not the bug I thought but glad to have found an inconsistency nonetheless.
How would you recommend dealing with b2, b3, b5, b6?
Is a cast necessary here?
Should the empty array be extracted to a constant? (That doesn't seem right. I have no guarantee the method won't mutate it).
Kindof expected it to be acceptable since it's an anonymous empty array (meaning afaik the subtype does not matter). Kindof how typescript does never[].
That depends on what type you expect bar(["A", "B", []]) to return. Do you want the return type _T to evaluate to str | list[str]? Or str | list[Any]? Or something else? Rather than using [], you could use list[str]() or list[Any]().
list[expected_subtype]() works great (python 3.9+) and it doesn't rely on casting! That syntax never crossed my mind, I'll have to remember that one. Thanks.
(in my actual use case the generic wasn't used for a return type, but with another optional parameter that I don't use, so I can really put w/e as the subtype)
Activity
erictraut commentedon Nov 29, 2022
I think pyright is correct to report an "unknown argument type" for the expressions assigned to
b5andb6, so I don't consider that a bug.However, I agree that there is an inconsistency here. The expressions
b2andb3should also generate the same error because they also include an "unknown" type argument. This is a bug.Calls to
foowill not generate the same error because bidirectional type inference causes[]to be inferred asIterable[Any]rather thanlist[Unknown]. Similarly,{}is inferred asIterable[Any]rather thandict[Unknown, Unknown].The expression
()always evaluates totuple[()]and is interpreted asIterable[Any], so that will never trigger the "unknown" checks.This will be addressed in the next release.
Fixed a bug that led to an incorrect type evaluation when an empty li…
Avasam commentedon Nov 29, 2022
Not the bug I thought but glad to have found an inconsistency nonetheless.
How would you recommend dealing with b2, b3, b5, b6?
Is a cast necessary here?
Should the empty array be extracted to a constant? (That doesn't seem right. I have no guarantee the method won't mutate it).
Kindof expected it to be acceptable since it's an anonymous empty array (meaning afaik the subtype does not matter). Kindof how typescript does
never[].erictraut commentedon Nov 29, 2022
That depends on what type you expect
bar(["A", "B", []])to return. Do you want the return type_Tto evaluate tostr | list[str]? Orstr | list[Any]? Or something else? Rather than using[], you could uselist[str]()orlist[Any]().Avasam commentedon Nov 29, 2022
list[expected_subtype]()works great (python 3.9+) and it doesn't rely on casting! That syntax never crossed my mind, I'll have to remember that one. Thanks.(in my actual use case the generic wasn't used for a return type, but with another optional parameter that I don't use, so I can really put w/e as the subtype)
erictraut commentedon Nov 30, 2022
This is addressed in pyright 1.1.282, which I just published. It will also be included in a future release of pylance.
Update pyright to 1.1.285 (#12)