Runtype: Runtime Type Validation and Multiple Dispatch
Runtype is a Python library providing utilities for fast run-time type validation and multiple dispatch. It enhances Python's built-in `dataclasses` with runtime type validation and automatic casting, offers smart alternatives to `isinstance` and `issubclass` for complex types, and implements a performant multiple-dispatch decorator. The library is currently at version 0.5.3, with a regular release cadence addressing bug fixes and performance improvements.
Common errors
-
TypeError: argument of type 'str' is not iterable
cause Attempting to iterate directly over an instance of a `runtype.dataclass` after version 0.4.0/0.5.0.fixInstead of `for item in my_dataclass_instance:`, use `my_dataclass_instance.asdict().items()` or access specific attributes: `my_dataclass_instance.field_name`. -
TypeError: Value '...' of type <class 'str'> is not an instance of type <class 'int'>
cause A `runtype.dataclass` received a value for a field that does not match its annotated type, and casting was not enabled or possible.fixEnsure that the input values strictly match the type hints in your `runtype.dataclass`. If you want `runtype` to attempt automatic type conversion, decorate your dataclass with `@dataclass(check_types='cast')`. -
TypeError: Can't dispatch on literal
cause `runtype.dispatch` does not support dispatching functions based on Python `Literal` types directly.fixRefactor your dispatch logic to use concrete types or broader type unions instead of `Literal` for dispatch arguments. `Literal` types are typically for static checking, not runtime dispatch values.
Warnings
- deprecated The behavior of `iter(dataclass_instance)` was deprecated in version 0.4.0 and formally removed/changed in 0.5.0.
- breaking The behavior of `Any` when used in type annotations was fixed in version 0.5.0 to align with `mypy`'s semantics. This might cause existing code relying on previous `Any` behavior to break.
- gotcha Prior to 0.3.5, dispatching on `dataclass.__init__` would override the built-in implementation. In 0.3.5+, it adds to it.
Install
-
pip install runtype
Imports
- isa
from runtype import isa
- dataclass
from runtype.dataclass import dataclass
- multidispatch
from runtype.dispatch import multidispatch
Quickstart
from runtype import isa
from runtype.dataclass import dataclass
# Example 1: Runtime type validation
assert isa({'a': 1, 'b': 2}, dict[str, int]) == True
assert isa([1, 'a', 3], list[int | str]) == True
assert not isa({'a': 'b'}, dict[str, int]) == True
# Example 2: Type-safe dataclass
@dataclass
class User:
name: str
age: int
email: str
try:
user = User(name='Alice', age=30, email='alice@example.com')
print(f"Valid user: {user.name}")
except TypeError as e:
print(f"Validation error: {e}")
try:
# This will raise a TypeError due to 'age' being a string
invalid_user = User(name='Bob', age='twenty', email='bob@example.com')
print(f"Invalid user: {invalid_user.name}")
except TypeError as e:
print(f"Validation error for invalid user: {e}")