[Python] Dynamically create Literal alias from list of valid values

Discussão em 'Python' iniciado por Stack, Fevereiro 7, 2025.

  1. Stack

    Stack Membro Participativo

    I have a function which validates its argument to accept only values from a given list of valid options. Typing-wise, I reflect this behavior using a Literal type alias, like so:

    from typing import Literal


    VALID_ARGUMENTS = ['foo', 'bar']

    Argument = Literal['foo', 'bar']


    def func(argument: 'Argument') -> None:
    if argument not in VALID_ARGUMENTS:
    raise ValueError(
    f'argument must be one of {VALID_ARGUMENTS}'
    )
    # ...


    This is a violation of the DRY principle, because I have to rewrite the list of valid arguments in the definition of my Literal type, even if it is already stored in the variable VALID_ARGUMENTS. How can I create the Argument Literal type dynamically, given the VALID_ARGUMENTS variable?

    The following things do not work:

    from typing import Literal, Union, NewType


    Argument = Literal[*VALID_ARGUMENTS] # SyntaxError: invalid syntax

    Argument = Literal[VALID_ARGUMENTS] # Parameters to generic types must be types

    Argument = Literal[Union[VALID_ARGUMENTS]] # TypeError: Union[arg, ...]: each arg must be a type. Got ['foo', 'bar'].

    Argument = NewType(
    'Argument',
    Union[
    Literal[valid_argument]
    for valid_argument in VALID_ARGUMENTS
    ]
    ) # Expected type 'Type[_T]', got 'list' instead


    Can it be done at all?

    Continue reading...

Compartilhe esta Página