beartype enforces type hints at O(1) constant time — the fastest Python runtime type checker. pip install beartype. Decorator: from beartype import beartype. @beartype def greet(name: str) -> str: return f"Hello, {name}". greet(123) raises BeartypeException. Class: @beartype class User: def __init__(self, name: str, age: int): self.name = name; self.age = age. O(1): beartype checks one random item from containers — not all items — so list[int] with 1 million items is as fast as with 10 items. Package: from beartype import beartype_this_package — call at package __init__.py to decorate all public functions without explicit decorators. from beartype.claw import beartype_package. beartype_package("myapp"). Config: from beartype.typing import BeartypeConf. @beartype(conf=BeartypeConf(strategy=BeartypeStrategy.O1)). Strict: BeartypeConf(is_pep484_tower=True) — treat float as supertype of int per PEP 484. is_bearable: from beartype.door import is_bearable. is_bearable(42, str) → False. is_bearable(42, int | str) → True. Never raises — returns bool. die_if_unbearable: from beartype.door import die_if_unbearable. die_if_unbearable(val, list[str]) — raises BeartypeException if not valid. Hint checkers: from beartype.door import is_subhint. is_subhint(int, float) → True (int ⊆ float per PEP 484). numpy: from beartype.vale import Is. from beartype.door import is_bearable. numpy dtype: NDArray[np.float64] — requires numpy. @beartype def normalize(arr: "np.ndarray") -> "np.ndarray". Suppress: from beartype.roar import BeartypeException. FastAPI: add @beartype to path function handlers for extra safety. pytest: from beartype import beartype; beartype_package("myapp") in conftest.py. Claude Code generates beartype decorators, package-level hooks, and is_bearable validation guards.
CLAUDE.md for beartype
## beartype Stack
- Version: beartype >= 0.18 | pip install beartype
- Decorator: @beartype on functions/classes — O(1) arg + return type checks
- Package: from beartype.claw import beartype_package; beartype_package("myapp")
- Predicate: from beartype.door import is_bearable — bool, never raises
- Assert: from beartype.door import die_if_unbearable — raises BeartypeException
- Config: @beartype(conf=BeartypeConf(is_pep484_tower=True)) for PEP-484 floats
- Speed: O(1) — checks ONE random item per container, not all items
beartype Runtime Type-Checking Pipeline
# app/typed_layer.py — beartype usage patterns
from __future__ import annotations
from dataclasses import dataclass, field
from decimal import Decimal
from enum import Enum
from typing import Literal, Optional, Union
from uuid import UUID, uuid4
from beartype import beartype
from beartype.door import die_if_unbearable, is_bearable, is_subhint
from beartype.roar import BeartypeException
from beartype.typing import BeartypeConf
# ─────────────────────────────────────────────────────────────────────────────
# Domain types
# ─────────────────────────────────────────────────────────────────────────────
class UserRole(str, Enum):
USER = "user"
MODERATOR = "moderator"
ADMIN = "admin"
class OrderStatus(str, Enum):
PENDING = "pending"
PAID = "paid"
SHIPPED = "shipped"
CANCELLED = "cancelled"
@beartype
@dataclass
class Address:
"""beartype applied to a dataclass checks __init__ arguments."""
street: str
city: str
state: str
postal_code: str
country: str = "US"
@dataclass
class User:
id: UUID
email: str
first_name: str
last_name: str
role: UserRole = UserRole.USER
is_active: bool = True
@dataclass
class OrderLine:
product_id: UUID
sku: str
quantity: int
unit_price: Decimal
# ─────────────────────────────────────────────────────────────────────────────
# 1. @beartype on functions — O(1) arg and return type checking
# ─────────────────────────────────────────────────────────────────────────────
@beartype
def create_user(
email: str,
first_name: str,
last_name: str,
role: Literal["user", "moderator", "admin"] = "user",
age: Optional[int] = None,
) -> User:
"""
beartype checks:
- email is str
- first_name is str
- role is exactly one of the three Literal values
- age is int OR None
- return value is User
All checks run in O(1) time.
"""
return User(
id=uuid4(),
email=email.lower(),
first_name=first_name,
last_name=last_name,
role=UserRole(role),
)
@beartype
def calculate_total(lines: list[OrderLine]) -> Decimal:
"""
O(1) list check: beartype samples ONE random element from `lines`.
For guaranteed exhaustive checking use die_if_unbearable with ALL_ITEMS.
"""
return sum(line.unit_price * line.quantity for line in lines, Decimal("0"))
@beartype
def apply_discount(
price: Decimal,
discount: float, # must be float, not str/int
code: str | None = None,
) -> Decimal:
if not (0.0 <= discount <= 1.0):
raise ValueError(f"discount must be 0–1, got {discount}")
final = price * Decimal(str(1 - discount))
return final.quantize(Decimal("0.01"))
@beartype
def get_user_role(user: User) -> UserRole:
return user.role
# ─────────────────────────────────────────────────────────────────────────────
# 2. is_bearable — safe boolean type predicate (never raises)
# ─────────────────────────────────────────────────────────────────────────────
def classify_id(value: object) -> str:
"""Use is_bearable for branching logic that depends on runtime type."""
if is_bearable(value, UUID):
return "uuid"
if is_bearable(value, int):
return "integer"
if is_bearable(value, str):
return "string"
return "unknown"
def is_valid_role(value: object) -> bool:
return is_bearable(value, Literal["user", "moderator", "admin"])
def is_prices_list(value: object) -> bool:
"""O(1) — samples one element."""
return is_bearable(value, list[Decimal])
def validate_dict_structure(data: object) -> bool:
"""Check that data is a dict[str, int] without raising."""
return is_bearable(data, dict[str, int])
# ─────────────────────────────────────────────────────────────────────────────
# 3. die_if_unbearable — inline assertion with structured error
# ─────────────────────────────────────────────────────────────────────────────
def process_event(payload: object) -> dict:
"""
Validate that payload is a dict before accessing keys.
die_if_unbearable raises BeartypeException with full type info on failure.
"""
die_if_unbearable(payload, dict)
die_if_unbearable(payload.get("type"), str) # type: ignore[union-attr]
die_if_unbearable(payload.get("event_id"), str) # type: ignore[union-attr]
return payload # type: ignore[return-value]
def assert_user_list(value: object) -> list[User]:
"""Assert value is list[User] — beartype samples one element (O(1))."""
die_if_unbearable(value, list[User])
return value # type: ignore[return-value]
# ─────────────────────────────────────────────────────────────────────────────
# 4. BeartypeConf — tuning
# ─────────────────────────────────────────────────────────────────────────────
# PEP 484 tower: is_pep484_tower=True treats int as subtype of float
_CONF_PEP484 = BeartypeConf(is_pep484_tower=True)
@beartype(conf=_CONF_PEP484)
def sum_amounts(amounts: list[float]) -> float:
"""
With is_pep484_tower=True, a list[int] is accepted as list[float]
— matches the PEP 484 numeric tower (int ⊆ float ⊆ complex).
Without it, beartype would reject list[int] when list[float] is expected.
"""
return sum(amounts)
# ─────────────────────────────────────────────────────────────────────────────
# 5. Safe error handling — BeartypeException
# ─────────────────────────────────────────────────────────────────────────────
def safe_is_bearable_check(value: object, hint: type) -> tuple[bool, str]:
"""
Returns (True, "") or (False, error_message).
is_bearable never raises, but die_if_unbearable does — use whichever fits.
"""
if is_bearable(value, hint):
return True, ""
try:
die_if_unbearable(value, hint)
return True, ""
except BeartypeException as exc:
return False, str(exc)
def validate_batch(items: list[object], expected_type: type) -> list[str]:
"""Validate each item individually — useful for reporting which items fail."""
errors = []
for i, item in enumerate(items):
ok, msg = safe_is_bearable_check(item, expected_type)
if not ok:
errors.append(f"item[{i}]: {msg}")
return errors
# ─────────────────────────────────────────────────────────────────────────────
# 6. Package-level instrumentation (call in __init__.py or conftest.py)
# ─────────────────────────────────────────────────────────────────────────────
def install_package_hook(package_name: str = "app") -> None:
"""
Call beartype_package() once to instrument ALL public functions in a package.
After this call, every function in `package_name` behaves as if @beartype
was applied, without modifying any source files.
Typical usage in conftest.py:
from beartype.claw import beartype_package
beartype_package("myapp")
Or in myapp/__init__.py:
from beartype.claw import beartype_this_package
beartype_this_package()
"""
from beartype.claw import beartype_package
beartype_package(package_name)
# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
# Valid function call
user = create_user("[email protected]", "Alice", "Smith", role="admin", age=30)
print(f"Created: {user.first_name} role={user.role.value}")
# Wrong arg type — BeartypeException
try:
create_user(123, "Alice", "Smith") # type: ignore[arg-type]
except BeartypeException as e:
print(f"BeartypeException: {e!s:.120}")
# Literal violation
try:
create_user("[email protected]", "Bob", "Jones", role="superuser") # type: ignore[arg-type]
except BeartypeException as e:
print(f"Literal error: {e!s:.80}")
# is_bearable — safe checks
print(f"\nis_bearable checks:")
print(f" 42 is int: {is_bearable(42, int)}")
print(f" 42 is str: {is_bearable(42, str)}")
print(f" None is Optional: {is_bearable(None, Optional[str])}")
print(f" 'admin' is Literal: {is_valid_role('admin')}")
print(f" 'root' is Literal: {is_valid_role('root')}")
# PEP 484 tower — int accepted as float
total = sum_amounts([1, 2, 3]) # list[int] OK with is_pep484_tower=True
print(f"\nsum_amounts([1,2,3]) = {total}")
# is_subhint — type hierarchy queries
print(f"\nis_subhint(int, float): {is_subhint(int, float)}") # True per PEP 484
print(f"is_subhint(str, int): {is_subhint(str, int)}") # False
# Batch validation
mixed = [1, 2, "oops", 4, None]
errors = validate_batch(mixed, int)
print(f"\nBatch errors: {errors}")
For the typeguard alternative — typeguard checks all items in a container when CollectionCheckStrategy.ALL_ITEMS is set, guaranteeing exhaustive validation at the cost of O(n) time, while beartype’s probabilistic O(1) sampling catches most bugs with near-zero overhead in production — 50–200× faster for large collections — and @beartype with beartype_this_package() instruments an entire package in one line with no per-function decoration. For the mypy alternative — mypy performs static analysis at development time but cannot validate values that enter the process at runtime (JSON payloads, database rows, config files), while die_if_unbearable(value, ExpectedType) validates runtime values against any PEP 484 compatible type hint including list[UUID], dict[str, Decimal], and Literal["pending", "paid"] — beartype effectively extends mypy’s guarantees to runtime boundaries. The Claude Skills 360 bundle includes beartype skill sets covering @beartype for O(1) function checking, @beartype on dataclasses for init validation, is_bearable for safe boolean predicates, die_if_unbearable for inline assertions, BeartypeConf with is_pep484_tower, beartype_package and beartype_this_package for whole-package hooks, BeartypeException handling, is_subhint for type hierarchy queries, pytest conftest integration, and combining beartype with mypy and typeguard for layered defence. Start with the free tier to try blazing-fast runtime type-checking code generation.