Open
Description
from typing import Literal, override
class Foo:
@override
def __eq__(self, value: object, /) -> bool:
return True
def fun(a: Foo | Literal["a"]) -> None:
if a == "a":
reveal_type(a) # Foo | Literal['a']
else:
reveal_type(a) # Foo | Literal['a']
in this case, it's safe to narrow to Foo
in the else
block, because the Literal["a"]
cannot have a custom __eq__
. this means if a == "a"
returns False
, there's no chance that a
is a Literal["a"]
, but if it returns True
then it's still possible for it to be a Foo
because of the Foo.__eq__
.
therefore, the narrowing should work like this:
def fun(a: Foo | Literal["a"]) -> None:
if a == "a":
reveal_type(a) # Foo | Literal['a']
else:
reveal_type(a) # Foo
this would also be consistent with pyright's behavior: playground