facebook / facebook/pyrefly

Incorrect union narrowing with `is EnumMember`

Open
#3,820 4 comments 0 reactions 1 assignee Claimed by @asukaminato0721 View on GitHub
help wanted msgspec narrowing stale typechecking
Dominant language
Rust
Stars
7k
Forks
519
PR merge metrics
No merged PRs in 30d

Description

I have a small repro of our real code in https://github.com/msgspec/msgspec/pull/1070#pullrequestreview-4497690765:

```python
from typing import final, Final, Literal, assert_type
import enum

@final
class UnsetType(enum.Enum):
UNSET = "UNSET"
def __bool__(self) -> Literal[False]: ...

UNSET: Final = UnsetType.UNSET

assert_type(UNSET, Literal[UnsetType.UNSET])

def check_unset_type_lowering(x: int | UnsetType) -> None:
if x is UNSET:
# this looks like a bug in `pyrefly`:
assert_type(x, Literal[UnsetType.UNSET])
```

fails with:

```
» pyrefly check ex.py
ERROR assert_type(UnsetType, Literal[UnsetType.UNSET]) failed [assert-type]
--> ex.py:16:20
|
16 | assert_type(x, Literal[UnsetType.UNSET])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
INFO 1 error
```

Both `mypy` and `pyright` pass this test.
The same happens if I change the condition to be:

```python
if x in UnsetType.UNSET:
assert_type(x, Literal[UnsetType.UNSET])
```

Version:

```
» pyrefly --version
pyrefly 1.0.0
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.