Skip to content

Inference failure in return statement with next and or #15755

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

Open
PGijsbers opened this issue Jul 23, 2023 · 1 comment · May be fixed by #18976
Open

Inference failure in return statement with next and or #15755

PGijsbers opened this issue Jul 23, 2023 · 1 comment · May be fixed by #18976
Labels
bug mypy got something wrong

Comments

@PGijsbers
Copy link

PGijsbers commented Jul 23, 2023

The following MWE (mypy-playground):

from typing import Iterator

def this_fails(numbers: Iterator[int]) -> int:
  return next(numbers, None) or 0
  
def intermediate_is_ok(numbers: Iterator[int]) -> int:
  my_number = next(numbers, None) or 0
  return my_number

def separate_line_is_ok(numbers: Iterator[int]) -> int:
  result = next(numbers, None)
  return result or 0
  
def using_default_directly_is_ok(numbers: Iterator[int]) -> int:
  return next(numbers, 0)

def having_optional_int_with_or_is_ok(number_maybe: int | None) -> int:
  return number_maybe or 0

produces the following report on master:

main.py:4: error: Argument 2 to "next" has incompatible type "None"; expected "int"  [arg-type]

This is incorrect as next(numbers, None) or 0 is always int.
All close variants, including assigning it to an intermediate variable, don't have this issue.
I can't think of an actual application where you would want to write code like this, but I figured it's an interesting interaction that might warrant investigation.

I couldn't find an open issue about this and I asked in Gitter.

@PGijsbers PGijsbers added the bug mypy got something wrong label Jul 23, 2023
@PascalPuchtler
Copy link

PascalPuchtler commented Jul 25, 2023

Hey, I am new here.
I worde a *.testfile to have a running and failing test case.
This is my current version

[case testIterator]
# flags: --python-version 3.10
from typing import Iterator
from typing import Iterable
from typing import TypeVar

E = TypeVar("E")
T = TypeVar("T")
def next(x: Iterable[T], default: E) -> T | E: ...

def this_fails(numbers: Iterator[int]) -> int:
  return next(numbers, None) or 0
  
def intermediate_is_ok(numbers: Iterator[int]) -> int:
  my_number = next(numbers, None) or 0
  return my_number

def separate_line_is_ok(numbers: Iterator[int]) -> int:
  result = next(numbers, None)
  return result or 0
  
def using_default_directly_is_ok(numbers: Iterator[int]) -> int:
  return next(numbers, 0)

def having_optional_int_with_or_is_ok(number_maybe: int | None) -> int:
  return number_maybe or 0

The test execution shows the same error as above
main:11: error: Argument 2 to "next" has incompatible type "None"; expected "int" (diff)

Can someone give me a hint, where i can find the implementation method next and or to fix this bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
2 participants