You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I stumbled upon some incomplete behavior related to Literal and Union. In most cases Union is not properly expanded upon conditional check when dealing with literals. Below example should describe clearly the situation.
fromtypingimportUnionfromtyping_extensionsimportLiteralclassA:
def__bool__(self) ->Literal[True]:
returnTrue@propertydefis_ok(self) ->Literal[True]:
returnTruedefok(self) ->Literal[True]:
returnTrueclassB:
def__bool__(self) ->Literal[False]:
returnFalse@propertydefis_ok(self) ->Literal[False]:
returnFalsedefok(self) ->Literal[False]:
returnFalsedefget_a_or_b() ->Union[A, B]: ...
thing=get_a_or_b()
ifthing:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'else:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'ifbool(thing):
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'else:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'ifthing.is_ok:
reveal_type(thing) # Revealed type is 'main.A'else:
reveal_type(thing) # Revealed type is 'main.B'ifthing.ok():
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'else:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'
I would expect that all examples will give the same result as the one with is_ok property. Maybe the bool() example would require some additional thought but it would seem wise to make it also work. Also, walrus operator makes it so that even the is_ok property example does not work. Other examples behave the same as before:
ifthing:=get_a_or_b():
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'else:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'ifbool(thing:=get_a_or_b()):
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'else:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'if (thing:=get_a_or_b()).is_ok:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'else:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'if (thing:=get_a_or_b()).ok():
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'else:
reveal_type(thing) # Revealed type is 'Union[main.A, main.B]'
The text was updated successfully, but these errors were encountered:
I opened PR #9288 that at least fixes the walrus operator usage for the property case. I would be grateful for any kind of feedback :)
I will try to also work on the rest of examples but it will probably take some time since I'm not that much familiar with the code base. And the rest of cases seems like a bit of work.
The bool() case is not so obvious so this probably would need to be discussed a bit more. I will probably try to fix the other examples first and then it can be decided whether it is reasonable to handle this bool() case.
…g in if statements (#9297)
This adds support for union narrowing in if statements when condition value has
defined literal annotations in `__bool__` method. Value is narrowed based on the
`__bool__` method return annotation and this works even if multiple instances
defines the same literal value for `__bool__` method return type.
This PR also works well with #9288 and
makes below example to work as expected:
```python
class A:
def __bool__(self) -> Literal[True]: ...
class B:
def __bool__(self) -> Literal[False]: ...
def get_thing() -> Union[A, B]: ...
if x := get_thing():
reveal_type(x) # Revealed type is '__main__.A'
else:
reveal_type(x) # Revealed type is '__main__.B'
```
Partially fixes#9220
Uh oh!
There was an error while loading. Please reload this page.
Used mypy version:
0.782
I stumbled upon some incomplete behavior related to
Literal
andUnion
. In most casesUnion
is not properly expanded upon conditional check when dealing with literals. Below example should describe clearly the situation.I would expect that all examples will give the same result as the one with
is_ok
property. Maybe thebool()
example would require some additional thought but it would seem wise to make it also work. Also, walrus operator makes it so that even theis_ok
property example does not work. Other examples behave the same as before:The text was updated successfully, but these errors were encountered: