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

Type inference of Tuples returns object instead #4975

Closed
eddieschoute opened this issue Apr 26, 2018 · 11 comments
Closed

Type inference of Tuples returns object instead #4975

eddieschoute opened this issue Apr 26, 2018 · 11 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-0-high

Comments

@eddieschoute
Copy link

eddieschoute commented Apr 26, 2018

While interacting with zip I encountered a variant of the following error:

error: No overload variant of "zip" matches argument types [builtins.list[builtins.int*], builtins.object*]

which is emitted by mypy on the case of

out = list(
    list(zip([1, 2], ordered_item))
    for item in [(1, 2), (4, 5)]
    for ordered_item in [item, tuple(reversed(item))]
    )
print(out)

This code runs normally on python 3.6.5, outputting:

[[(1, 1), (2, 2)], [(1, 2), (2, 1)], [(1, 4), (2, 5)], [(1, 5), (2, 4)]]

Expected Behavior

Mypy should infer that ordered_item is a tuple, or at least an iterable so that zip can be applied on it.

It may also be interesting to consider the case where ordered_item is heterogenous over different Iterables (i.e. not only tuples). Would Iterable be inferred then?

Actual Behavior

Mypy infers the object type on ordered_item which you understandably cannot zip.

By explicitly casting item to tuple the error message is resolved:

out = list(
    list(zip([1, 2], ordered_item))
    for item in [(1, 2), (4, 5)]
    for ordered_item in [tuple(item), tuple(reversed(item))]
    )
print(out)

Environment

OS: macOS 10.13
Python: 3.6.5
mypy: 0.590

@ilevkivskyi
Copy link
Member

Yes, this looks like a bug. Most likely it is because join of tuples is still pretty basic (in particular a case of joining fixed length tuple and variable length tuple is not covered).

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal labels May 7, 2018
@ilevkivskyi
Copy link
Member

A simple repro:

x: Tuple[int, int]
y: Tuple[int, ...]
lst = [x, y]
reveal_type(lst[0])  # Revealed type is 'builtins.object*'

Clearly the type should be Tuple[int, ...] in this case.

@beamerblvd
Copy link

beamerblvd commented Jun 28, 2018

Is this fix available in a release yet?

@ethanhs
Copy link
Collaborator

ethanhs commented Jun 28, 2018

@beamerblvd I'm not sure I understand. I don't think there is a fix for this yet

@beamerblvd
Copy link

@ethanhs, my mistake. I saw a red Closed and thought it was for this issue, but it was for another issue having reference this.

@ilevkivskyi
Copy link
Member

This already appeared five times, so I am raising priority to high (especially since IIUC we are not going to infer unions for ternary expressions). This should be not hard to fix if someone wants to try.

@intgr
Copy link
Contributor

intgr commented Jan 13, 2020

Another minimal reproducer:

tup1: tuple = ()
tup2 = tup1 if input() else ()
reveal_type(tup2)   # N: Revealed type is 'builtins.object'

What is even happening here? 😄

@JelleZijlstra
Copy link
Member

@intgr the underlying problem is that internally in mypy, the types for fixed-length tuples (like Tuple[int, int] and variadic tuples (Tuple[int, ...]) are completely separate, so when mypy tries to join these two types, it lands on object instead of something more reasonable.

JukkaL pushed a commit that referenced this issue Jan 31, 2020
…8335)

For example:

* Tuple[int] + Tuple[bool, ...] becomes Tuple[int, ...]
* List[int] + Tuple[bool, ...] becomes Sequence[int]

Previously Mypy simply punted and returned `object`.

This solves the other part of issue #4975. Fixes issue #8074.
JukkaL pushed a commit that referenced this issue Feb 3, 2020
For example:
Tuple[bool, int] + Tuple[bool] becomes Tuple[int, ...]

Previously Mypy simply punted and returned `object`.

This solves part of #4975.
@JukkaL
Copy link
Collaborator

JukkaL commented Feb 3, 2020

@intgr Do you think that this issue can be closed now, after you've PRs were merged?

@intgr
Copy link
Contributor

intgr commented Feb 3, 2020

Yes, that should solve all the cases involving tuples. Also #8074 can be closed, as it falls back to Sequence[] type.

@ethanhs
Copy link
Collaborator

ethanhs commented Feb 3, 2020

Closing as it was fixed in #8335. I'm very happy to see this issue fixed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-0-high
Projects
None yet
Development

No branches or pull requests

7 participants