[Python] Create Literal type from constant variables

Discussão em 'Python' iniciado por Stack, Março 15, 2025.

  1. Stack

    Stack Membro Participativo

    I want to use "constant" variables in my typing definitions, something like this:

    FOO = "foo"
    BAR = "bar"

    @dataclass
    class Event():
    name: Literal[FOO, BAR]


    But that is illegal code for mypy.

    This works, but then I cannot use the variables in my code:

    FOO = Literal["foo"]
    BAR = Literal["bar"]

    @dataclass
    class Event():
    name: FOO | BAR

    Event(FOO) # gives: Event(name=typing.Literal['foo'])


    Is there a way to get this to work without defining FOO and BAR twice?


    Impelenting Marks answer (https://stackoverflow.com/a/76382060/5386216) works, but then mypy is not able to distinguish types based on the event name:

    class FooBar(Enum):
    FOO = "foo"
    BAR = "bar"

    @dataclass
    class StringEvent:
    name: Literal[FooBar.FOO]
    value: str


    @dataclass
    class NumberEvent:
    name: Literal[FooBar.BAR]
    value: int


    def handle_event(event: StringEvent | NumberEvent):
    if event.name == FooBar.FOO:
    event.value.upper() # should not give a mypy error

    if event.name == FooBar.BAR:
    event.value.upper() # Should give a mypy error


    Both both cases of event.value.upper() give the following mypy error: Item "int" of "Union[str, int]" has no attribute "upper"

    Continue reading...

Compartilhe esta Página