Would it be reasonable to define in the typing specification that that a literal of all elements of an enum should be treated equally to the enum itself in type annotations?
For example:
import enum
import typing as t
class Importance(enum.IntEnum):
LOW = 1
MEDIUM = 2
HIGH = 3
type AllT = t.Literal[Importance.LOW, Importance.MEDIUM, Importance.HIGH]
class Task[T: Importance]:
...
def manage_task(task: Task[AllT]) -> t.Any:
...
task: Task[Importance] = ...
manage_task(task) # error
This function call would currently show a typing error. Obviously this example is made up and not too sensical but you get the gist.
Would defining this make sense or are there reasons to not allow this?
Yes, type checkers should already do this. Both the type Importance and the type Literal[Importance.LOW, Importance.MEDIUM, Importance.HIGH] contain the same values and therefore should be treated as equivalent under the typing spec.
Checking in multiplay: ty, pyrefly, mypy, and pycroscope already accept your program. Pyright and zuban do not; that’s best seen as a bug in those type checkers.
I was curious so I checked the references in typing specification and it’s indeed explicitly spelled out in #enum-literal-expansion.
Likewise, a type checker should treat a complete union of all literal members as equivalent to the enum type:
With that called out specially in the spec I would have guessed it was included in the conformance test-suite . (I’ll probably check and dig a bit deeper).
I will add an issue there. I did some checks and there were indeed a check but only when returning a parameterized type, not as accepting it as an argument.