The Python Oracle

Determining if object is of typing.Literal type

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzling Curiosities

--

Chapters
00:00 Question
00:46 Accepted answer (Score 0)
01:03 Answer 2 (Score 1)
01:20 Answer 3 (Score 0)
02:10 Thank you

--

Full question
https://stackoverflow.com/questions/7077...

Answer 2 links:
[typing.getOrigin(tp)]: https://docs.python.org/3.9/library/typi...
[typing.Literal]: https://docs.python.org/3.9/library/typi...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #typehinting #literals #pythontyping #typing

#avk47



ANSWER 1

Score 8


typing.get_origin() returns Literal for Literal descendants, so what I needed is basically

if get_origin(GameState) == Literal:
    # do sth



ACCEPTED ANSWER

Score 2


typing.get_origin(tp) is the proper way

It was implemented in Python 3.8 (Same as typing.Literal)

The docstring is thoroughly instructive:

def get_origin(tp):
    """Get the unsubscripted version of a type.

    This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
    and Annotated. Return None for unsupported types. Examples::

        get_origin(Literal[42]) is Literal
        get_origin(int) is None
        get_origin(ClassVar[int]) is ClassVar
        get_origin(Generic) is Generic
        get_origin(Generic[T]) is Generic
        get_origin(Union[T, int]) is Union
        get_origin(List[Tuple[T, T]][int]) == list
    """

In your use case it would be:

from typing import Literal, get_origin

def parse_values(ann):
    if isinstance(ann, str):
        return "str"
    elif isinstance(ann, int):
        return "int"
    elif get_origin(ann) is Literal:
        return "Literal"

assert parse_values("foo") == "str"
assert parse_values(5) == "int"
assert parse_values(Literal["bar", 6]) == "Literal"