Skip to content
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

zip silently returns Any because of loose join with star types #3370

Open
ilevkivskyi opened this issue May 16, 2017 · 7 comments
Open

zip silently returns Any because of loose join with star types #3370

ilevkivskyi opened this issue May 16, 2017 · 7 comments
Labels
bug mypy got something wrong priority-1-normal

Comments

@ilevkivskyi
Copy link
Member

y: List[Tuple[int]]
reveal_type(zip(*y))  # Revealed type is 'Any'

I think this is a bug since we should never silently infer Any from a precisely typed call.

@ilevkivskyi
Copy link
Member Author

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.

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal labels May 16, 2017
@gvanrossum
Copy link
Member

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

@ilevkivskyi
Copy link
Member Author

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 #3194), so that I would just "tighten" the join.

@gvanrossum
Copy link
Member

Is this the rigvt tissue for that?

@ilevkivskyi
Copy link
Member Author

I didn't find any other issue for this, so I propose to track this here.

@ilevkivskyi ilevkivskyi changed the title zip silently returns Any zip silently returns Any because of loose join with star types May 17, 2017
@JukkaL
Copy link
Collaborator

JukkaL commented May 18, 2017

This seems pretty similar to #1322. Also, #3256 is related.

@erictraut
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-1-normal
Projects
None yet
Development

No branches or pull requests

4 participants