Introduction
Runtime type checking libraries like typeguard and beartype enforce type annotations at runtime, catching type errors before they cause issues.
Typeguard Basic Usage
from typeguard import typechecked
@typechecked
def greet(name: str, age: int) -> str:
return f"Hello {name}, you are {age}"
greet("Alice", 30) # Works
greet("Bob", "thirty") # TypeError!
Typeguard for Classes
from typeguard import typechecked
@typechecked
class Person:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def set_age(self, age: int):
self.age = age
person = Person("Alice", 30)
person.set_age("thirty") # TypeError!
Beartype Usage
from beartype import beartype
@beartype
def calculate(x: int, y: int) -> int:
return x + y
@beartype
class Point:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
Configuration
from typeguard import install_import_hook
install_import_hook("mymodule")
# Or configure globally
from typeguard.config import CollectionCheckStrategy
CollectionCheckStrategy.ALL_ITEMS
Performance Considerations
# Use sparingly in production due to overhead
# For debugging/development
from typeguard import typechecked
# For production, consider:
# 1. Type checking only in tests
# 2. Using __debug__ guards
# 3. Using type annotations for documentation only
Custom Type Checkers
from typeguard import TypeHintTypeChecker
@TypeHintTypeChecker
class CustomValidator:
pass
# Or register custom type checkers
from typeguard import add_type_checker
@add_type_checker
class Email(str):
pass
Practice Problems
- Add type checking to a function
- Use beartype with custom types
- Configure type checking for a module
- Implement custom type validator
- Compare performance with static typing