Typeguard
Typeguard is a Python library that provides run-time type checking for functions and methods defined with PEP 484 type annotations, as well as for arbitrary objects. It acts as an additional layer of type safety alongside static type checkers like MyPy, catching type violations that can only be detected at run time. Currently at version 4.5.1, the library is actively maintained with regular updates.
Warnings
- breaking Version 4.5.0 introduced a breaking change where `check_argument_types()` started receiving an unexpected keyword argument 'memo', causing issues in downstream libraries.
- gotcha The `@typechecked` decorator becomes a no-op when Python is run in optimized mode (`python -O` or by setting the `PYTHONOPTIMIZE` environment variable). This can lead to silent disabling of runtime type checks in production environments.
- deprecated Direct use of `check_argument_types()` and `check_return_type()` has limitations, such as not working reliably with dynamically defined type hints (e.g., in nested functions) and being less comprehensive than the `@typechecked` decorator.
- breaking Typeguard has dropped support for Python 3.8 in recent major versions (e.g., in the 4.x series).
Install
-
pip install typeguard
Imports
- typechecked
from typeguard import typechecked
- check_type
from typeguard import check_type
- install_import_hook
from typeguard import install_import_hook
- suppress_type_checks
from typeguard import suppress_type_checks
- typeguard_ignore
from typeguard import typeguard_ignore
- check_argument_types
from typeguard import check_argument_types
Quickstart
from typeguard import typechecked
from typing import List
@typechecked
def process_data(data: List[int], multiplier: float) -> List[float]:
"""Processes a list of integers, multiplies each by a float, and returns a list of floats."""
return [item * multiplier for item in data]
@typechecked
class MyCalculator:
def __init__(self, offset: int):
self.offset = offset
def add(self, a: int, b: int) -> int:
return a + b + self.offset
# --- Successful usage ---
print(f"Processed data: {process_data([1, 2, 3], 2.5)}") # Expected: [2.5, 5.0, 7.5]
calculator = MyCalculator(offset=10)
print(f"Calculator sum: {calculator.add(5, 7)}") # Expected: 22
# --- Intentional type errors (will raise TypeError) ---
try:
process_data([1, '2', 3], 2.5) # data contains a string instead of int
except TypeError as e:
print(f"Caught expected error (list item type): {e}")
try:
process_data([1, 2, 3], '2.5') # multiplier is a string instead of float
except TypeError as e:
print(f"Caught expected error (argument type): {e}")
try:
calculator.add(5, 'seven') # b is a string instead of int
except TypeError as e:
print(f"Caught expected error (method argument type): {e}")