Given:
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
Is there a type expression Foo such that:
Foo[Color] = Literal["RED", "GREEN", "BLUE"]
Given:
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
Is there a type expression Foo such that:
Foo[Color] = Literal["RED", "GREEN", "BLUE"]
From PEP 586 -- Literal Types
Legal parameters for Literal at type check time
Literal[Color.RED] # Assuming Color is some enum
Also in PEP 586:
Literals, enums, and forward references
Literal["Color.RED"](...) In cases like these, we always assume the user meant to construct a literal string."Literal[Color.RED]"(...) If the user wants a forward reference, they must wrap the entire literal type in a string
from typing import Literal
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
FIRST = Literal["RED", "GREEN", "BLUE"]
SECOND = Literal[Color.RED, Color.GREEN]
THIRD = Literal["Color.RED", "Color.GREEN"]
def one(arg: FIRST):
print("FIRST")
def two(arg: SECOND):
print("SECOND")
def three(arg: THIRD):
print("THIRD")
one("GREEN") # Linter issues no warning
one(Color.RED) # Expected type 'Literal["RED", "GREEN", "BLUE"]', got 'Color' instead
one(Color.RED.name) # Expected type 'Literal["RED", "GREEN", "BLUE"]', got 'str' instead
two("RED") # Expected type 'Color', got 'str' instead
two(Color.RED) # Linter issues no warning
three("RED") # Expected type 'Literal["Color.RED", "Color.GREEN"]', got 'Literal["RED"]' instead
three("Color.RED") # Linter issues no warning
three(Color.RED.name) # Expected type 'Literal["Color.RED", "Color.GREEN"]', got 'str' instead
If you want to declare the Literal by passing as argument a collection of Enum members I think that isn't possible (see: Illegal parameters for Literal at type check time) the static type checker gives the following warning:
'Literal' may be parameterized with literal ints, byte and unicode strings, bools, Enum values, None, other literal types, or type aliases to other literal types
Can't use starred expression here
teste_one = ("RED", "GREEN", "BLUE")
FIRST = Literal[teste_one]
FIRST = Literal[*teste_one]
test_two = Color.__members__.keys()
SECOND = Literal[test_two]
SECOND = Literal[*test_two]
You'll always have to declare the arguments to Literal[...] explicitly.
You could use Enum name programmatic access for a similar effect like :
class Colors(Enum):
RED = 1
GREEN = 2
BLUE = 3
ColorsNames = [color.name for color in Colors]
print(ColorsNames)
['RED', 'GREEN', 'BLUE']