Если вы использовали Pydantic или FastAPI, вы видели, как аннотации типов магическим образом проверяют входящие данные. Но как реализовать это самому, используя только стандартную библиотеку Python?
Ключ к разгадке —
typing.Annotated. Этот механизм позволяет добавлять произвольные метаданные к типам, которые Python игнорирует при проверке типов, но которые мы можем прочитать во время выполнения программы.1️⃣ Как достать метаданные
Для этого используется функция
get_type_hints с флагом include_extras=True.
import typing as t
from dataclasses import dataclass
@dataclass
class User:
age: t.Annotated[int, "должен быть > 0"]
# Получаем: {'age': typing.Annotated[int, 'должен быть > 0']}
annotations = t.get_type_hints(User, include_extras=True)
2️⃣ Реализация своего валидатора
Автор предлагает элегантное решение: использовать frozen dataclasses и метод
__post_init__ для автоматической проверки полей сразу после создания объекта.Основные шаги:
1. Перебираем все аннотации класса.
2. Ищем в метаданных объекты, которые можно вызвать (`callable`).
3. Применяем их к значениям атрибутов.
4. Используем
object.__setattr__, чтобы обойти ограничение неизменяемости (frozen).3️⃣ Группировка ошибок (Exception Groups)
В Python 3.11 появились
ExceptionGroup, и автор мастерски применяет их здесь. Вместо того чтобы падать на первой же ошибке, валидатор собирает все нарушения и выбрасывает их одним списком. Это критично для удобства API и фронтенда.
class ValidationErrorGroup(ExceptionGroup):
pass
# В итоге при ошибке вы получите детальный отчет:
# ValidationErrorGroup: Validation Errors (2 sub-exceptions)
# ├── ValueError: -1 must be > to 0 (attribute 'x')
# └── ValueError: String is empty (attribute 'y')
4️⃣ Классы против Замыканий
Автор сравнивает два подхода к созданию правил:
✅ Вызываемые классы (как в Pydantic): Удобно читать, легко настраивать через аргументы
__init__.✅ Замыкания (Closures) и
partial: Более функциональный стиль, который позволяет изящно комбинировать проверки, например: Annotated[int, gte(0), lt(100)].🔗 Ссылка на оригинальный пост
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека питониста
#буст
