2022-04-01

Literal Types in Python

Literal Types in Python

Introduced in Python 3.8, typing.Literal is used to specify a type that is constrained to one or more specific values. For instance, Literal[1, 2, 3] indicates a type that is either 1, 2, or 3. This can be used in conjunction with other type hints to create more precise type annotations.

typing.Literal does not check these constraints at runtime, but they are checked by type checkers, linters, and IDE features. This can help find bugs before running the code, and it makes your code more self-documenting.

Syntax of typing.Literal

The basic syntax is Literal[val1, val2, ...] where val1, val2, ... are the concrete values. Here's a basic usage example:

python
from typing import Literal

def get_status(status: Literal["connected", "disconnected", "idle"]) -> None:
    pass

In this example, the get_status function is expected to receive one of the three status strings. Anything else will be considered incorrect by a type checker, though Python itself will not enforce this at runtime.

Literal types are mostly used when a function expects only a certain set of values. For instance, a function that handles HTTP methods might only accept the methods "GET", "POST", "PUT", "DELETE", and so on. Literal types can make this explicit.

python
from typing import Literal, Optional, Dict, Any

def handle_request(method: Literal["GET", "POST", "PUT", "DELETE"], url: str, data: Optional[Dict[str, Any]] = None) -> None:
    pass

In this example, the handle_request function is expected to receive one of the four HTTP methods as a string. Any other value would be flagged by a type checker. This helps make the code more self-documenting, and it can help catch bugs before running the code.

Comparing Literal Types and Enumerations

typing.Literal and Enum serve a similar purpose: they both restrict a value to a limited set of options. But there are some differences:

  • Typing Information
    With typing.Literal, you specify the exact value(s) a variable can take. With enum.Enum, you create distinct values, and the type of the variable is the enum itself, not the value of the enum item.

  • Runtime Checking
    Python's enums are checked at runtime. If you try to assign an invalid value to an enum, you get a runtime error. typing.Literal, on the other hand, doesn't provide runtime guarantees. Its constraints are only checked by type checkers, linters, and IDE features.

  • Code Clarity
    Enums can make your code more self-documenting. With typing.Literal, you see the specific values it can take, which can also be informative, but you don't get a semantic label.

References

https://peps.python.org/pep-0586/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!