microsoft / microsoft/pyright

Enum type not assignable to complete union of its literal members

Open
#11,169 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
15.6k
Forks
1.8k
Avg merge
12h 13m
Merged PRs (30d)
52

Description

**Describe the bug**
According to the [typing spec for enums](https://typing.python.org/en/latest/spec/enums.html#enum-literal-expansion),

> a type checker should treat a complete union of all literal members as equivalent to the enum type, but not from the enum type to the union.

However, Pyright currently only allows assignment from the union to the enum type, but not from the enum type to the union.

**Code or Screenshots**

```python
from enum import Enum
from typing import Literal

class Color(Enum):
RED = "red"
GREEN = "green"
BLUE = "blue"

def contraction_id(c: Literal[Color.RED, Color.GREEN, Color.BLUE]) -> Color:
return c

def expansion_id(c: Color) -> Literal[Color.RED, Color.GREEN, Color.BLUE]:
return c
```

The error reported is

```
Type "Color" is not assignable to return type "Literal[Color.RED, Color.GREEN, Color.BLUE]"
Type "Color" is not assignable to type "Literal[Color.RED, Color.GREEN, Color.BLUE]"
"Color" is not assignable to type "Literal[Color.RED]"
"Color" is not assignable to type "Literal[Color.GREEN]"
"Color" is not assignable to type "Literal[Color.BLUE]" (reportReturnType)

```

**VS Code extension or command-line**

[Pyright playground](https://pyright-play.net/?code=GYJw9gtgBApgdgV2gSwgBzCALlAooiAKFEiiwE81k4BzKVDbKAGWSxhAEMAbQwgY26cAzsKgBhMN0wAKfEgCUALkJQ1UAEq4AIlAC8UAEQgYAE0Or1AcS24AcvqM0T8C%2BqgAhZgFVcjwwBG3AgwFoSmMMBQ-GBwWFz8WMixAPrIpjIAHkosbBw8ANqS0iAAdFraADQSUpilNrj21cV1Xr4AugpQALQAfDUlKu4mWAggcFCZfBFRMJlonHDCyXBpGdkDmF19uexc3EW1ZRXNR-W2dqclpW247UPqI2MTU0A)

Contributor guide

Open the contributing guide

Research direction

Start with the Pyright playground reproduction and compare the reported behavior with the typing spec's enum literal expansion rules. Trace how the checker handles the return from expansion_id; done means the complete literal union is accepted as the return type without the reported diagnostic.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.