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

Can't convert from Tuple of optional to Tuple of non-optional #8622

Open
kventinel opened this issue Apr 2, 2020 · 7 comments
Open

Can't convert from Tuple of optional to Tuple of non-optional #8622

kventinel opened this issue Apr 2, 2020 · 7 comments
Labels
false-positive mypy gave an error on correct code feature priority-2-low

Comments

@kventinel
Copy link

kventinel commented Apr 2, 2020

Code:

from typing import Tuple, Optional

a: Tuple[Optional[int], Optional[int]] = (1, 1)
b: Tuple[int, int]
if a[0] is not None and a[1] is not None:
    b = a

After that has error:

script.py:6: error: Incompatible types in assignment (expression has type "Tuple[Optional[int], Optional[int]]", variable has type "Tuple[int, int]")

Expected no error.
I have: mypy-0.770 and Python 3.7.7

@JelleZijlstra
Copy link
Member

Did you mean to use and instead of or? (I haven't checked whether mypy handles that case correctly.)

@kventinel
Copy link
Author

Ohhh. Sorry for wrong example. Yes, I mean and instead of or. Currently fix it and got same error.

@msullivan
Copy link
Collaborator

It works to write b = a[0], a[1]. I think propagating that fact up to the type of a itself is probably not something we're going to support.

@kventinel
Copy link
Author

kventinel commented Apr 4, 2020

Why? Without this given error look strange. And tuple can have more than 2 element, in this case line with "crutch" will be too long.

Also I have example with cast list of optional to list of non-optional and double check on None.

from typing import Tuple, Optional, List
from typing import Tuple, Optional, List


def case0() -> None:
    a: Tuple[Optional[int], Optional[int]] = (1, 1)
    b: Tuple[int, int]
    if a[0] is not None and a[1] is not None:
        b = a  # wrong
        b = a[0], a[1]  # good


def case1() -> None:
    a: List[Optional[int]] = [1] * 100
    b: List[int]
    if all([i is not None for i in a]):
        b = a  # wrong
        b = [i for i in a]  # wrong
        b = [a[i] for i in range(len(a))]  # wrong
        b = [i for i in a if i is not None]  # good
    if all([a[i] is not None for i in range(len(a))]):
        b = a  # wrong
        b = [i for i in a]  # wrong
        b = [a[i] for i in range(len(a))]  # wrong
        b = [i for i in a if i is not None]  # good

Errors:

script.py:8: error: Incompatible types in assignment (expression has type "Tuple[Optional[int], Optional[int]]", variable has type "Tuple[int, int]")
script.py:16: error: Incompatible types in assignment (expression has type "List[Optional[int]]", variable has type "List[int]")
script.py:17: error: List comprehension has incompatible type List[Optional[int]]; expected List[int]
script.py:18: error: List comprehension has incompatible type List[Optional[int]]; expected List[int]
script.py:21: error: Incompatible types in assignment (expression has type "List[Optional[int]]", variable has type "List[int]")
script.py:22: error: List comprehension has incompatible type List[Optional[int]]; expected List[int]
script.py:23: error: List comprehension has incompatible type List[Optional[int]]; expected List[int]

@JukkaL
Copy link
Collaborator

JukkaL commented Apr 9, 2020

@kventinel The reason why we are unlikely to support this is that the implementation looks non-trivial and this use case seems quite rare, relative some other use cases that we also don't support well. So at least the fix would be low priority.

About your other examples: you can create separate issues about these; we'll consider each case where type inference goes wrong separately.

@kventinel
Copy link
Author

But what so non-trivial in the implementation? I think, it's not so difficult propagate new type to element of fixed size tuple as it's work with single value.

And I think, that my other examples even more non-trivial than first:)

And I think, this issue must be reopened as bug (even if it would be low priority).

@JukkaL
Copy link
Collaborator

JukkaL commented Apr 9, 2020

Fair enough. If somebody comes up with a simple enough implementation, we will consider merging a PR.

@JukkaL JukkaL reopened this Apr 9, 2020
@JukkaL JukkaL added false-positive mypy gave an error on correct code feature priority-2-low labels Apr 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
false-positive mypy gave an error on correct code feature priority-2-low
Projects
None yet
Development

No branches or pull requests

4 participants