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:
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.
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
Withtyping.Literal
, you specify the exact value(s) a variable can take. Withenum.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. Withtyping.Literal
, you see the specific values it can take, which can also be informative, but you don't get a semantic label.
References