pyre-check
pyre-check copied to clipboard
Type narrowing with isinstance doesn't work when the first argument is a walrus-operator assignment
Bug description
As pyre is quite strict with the type narrowing of non-final attributes (which I don't mind), I want to use the walrus operator to make the type narrowing more convenient, but it doesn't seem to play nice with isinstance().
Reproduction steps
from dataclasses import dataclass
@dataclass
class A:
x: str | int
def f(self) -> int:
if isinstance(y := self.x, int):
reveal_type(y) # Revealed type for `y` is `typing.Union[int, str]`.
reveal_type(self.x) # Revealed type for `self.x` is `typing.Union[int, str]`.
return y + 2 # Error: `+` is not supported for operand types `typing.Union[int, str]` and `int`.
return 0
Expected behavior
The type of y should be int because I just narrowed it.
Actual behavior
The type of y is not narrowed.
Additional context It works fine in mypy and pyright.
Furthermore, the following works fine in pyre:
from dataclasses import dataclass
@dataclass
class B:
x: str | int
def f(self) -> int:
y = self.x
if isinstance(y, int):
reveal_type(y) # Revealed type for `y` is `int`.
reveal_type(self.x) # Revealed type for `self.x` is `typing.Union[int, str]`.
return y + 2
return 0
pyre version
Binary version: d4aef6ea269d577faf9a2a503032fda33f725936
Client version: 0.9.17
I see there was already a TODO for this
https://github.com/facebook/pyre-check/blob/2da1844a4ae1861bf5b765a80feaf463a62d8831/source/analysis/test/integration/isinstanceTest.ml#L400-L407
I think @stroxler recently fixed this, it should be available with the next open source release