pythontyping

What's the difference between Literal and Union in Python typing?


What's the difference between Literal and Union in Python typing?

I can't see any difference between them. Could anyone explain this?

My IDE didn't respond to me when I use like Union[2,3].


Solution

  • Union[x, y] means "either x or y". Literal[5, 6] means "literally 5 or literally 6" (not some variable that's equal to any of those, but literally 5 or 6).

    The difference is that the arguments of Union must be types. The arguments to Literal are literals. Type names (like int, float, MyClass) are not literals (but they do represent types), so they can't be used in Literal. Literals (like 5, 'Hello!' and [1,2,3]) are not types, so they cannot be used in Union.

    For example, these types are not correct:

    Literal[str, float]  # none of the arguments are literals
    Union[5, 6] # none of the arguments are types
    

    In response to your comment, None is both a literal and a type.

    None is defined as a literal in Python's grammar:

    atom: ('(' [yield_expr|testlist_comp] ')' |
           '[' [testlist_comp] ']' | # maybe list literal
           '{' [dictorsetmaker] '}' | # maybe dict/set literal
           NAME |  # NOT a literal
           NUMBER | # int/float literal
           STRING+ | # string literal
           '...' | # Ellipsis literal
           'None' | # None literal!
           'True' | 'False')
    

    Here, None is a literal, thus, it can be used in Literal. However, it's not a class:

    >>> import inspect
    >>> inspect.isclass(None)
    False
    >>> inspect.isclass(5)
    False
    >>> inspect.isclass(str)
    True
    

    So, it can't be used in Union. BUT it actually is used in Union: Union[str, None] means "type str or nothing". From the docs on Union:

    You can use Optional[X] as a shorthand for Union[X, None]