[red-knot] Fix Leaking Narrowing Constraint in ast::ExprIf (#14590)
## Summary Closes #14588 ```py x: Literal[42, "hello"] = 42 if bool_instance() else "hello" reveal_type(x) # revealed: Literal[42] | Literal["hello"] _ = ... if isinstance(x, str) else ... # The `isinstance` test incorrectly narrows the type of `x`. # As a result, `x` is revealed as Literal["hello"], but it should remain Literal[42, "hello"]. reveal_type(x) # revealed: Literal["hello"] ``` ## Test Plan mdtest included! --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
@@ -22,3 +22,22 @@ reveal_type(1 if None else 2) # revealed: Literal[2]
|
||||
reveal_type(1 if "" else 2) # revealed: Literal[2]
|
||||
reveal_type(1 if 0 else 2) # revealed: Literal[2]
|
||||
```
|
||||
|
||||
## Leaked Narrowing Constraint
|
||||
|
||||
(issue #14588)
|
||||
|
||||
The test inside an if expression should not affect code outside of the block.
|
||||
|
||||
```py
|
||||
def bool_instance() -> bool:
|
||||
return True
|
||||
|
||||
x: Literal[42, "hello"] = 42 if bool_instance() else "hello"
|
||||
|
||||
reveal_type(x) # revealed: Literal[42] | Literal["hello"]
|
||||
|
||||
_ = ... if isinstance(x, str) else ...
|
||||
|
||||
reveal_type(x) # revealed: Literal[42] | Literal["hello"]
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user