/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.2.0
src/liquidcode/validation.py
135 строк
4 KB
User
0.3.0-RC - Добавлена система валидации (Validator, базовые валидаторы, интеграция с ArgumentResolver, генератор `make:validator`)
04 июл 2026, 13:30
04 июл 2026, 13:30
6b33e13
Код
Авторство
О чём код?
""" Система валидации для LiquidCode. Предоставляет базовые валидаторы, декоратор @validate и интеграцию с ArgumentResolver. """ import re from dataclasses import dataclass from typing import Any, Dict, List, Type, Union class ValidationError(Exception): """Исключение, выбрасываемое при ошибках валидации.""" def __init__(self, errors: Dict[str, List[str]]): self.errors = errors super().__init__(str(errors)) @dataclass class Constraint: """Базовый класс для ограничений валидации.""" message: str = "Invalid value" class Required(Constraint): """Поле обязательно для заполнения.""" def __call__(self, value: Any) -> bool: return value is not None and value != '' class Email(Constraint): """Проверка email адреса.""" pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$') def __call__(self, value: str) -> bool: if value is None: return False return bool(self.pattern.match(value)) class MinLength(Constraint): """Минимальная длина строки.""" def __init__(self, length: int, message: str = None): self.length = length self.message = message or f"Минимальная длина {length} символов" def __call__(self, value: str) -> bool: return len(value) >= self.length class MaxLength(Constraint): """Максимальная длина строки.""" def __init__(self, length: int, message: str = None): self.length = length self.message = message or f"Максимальная длина {length} символов" def __call__(self, value: str) -> bool: return len(value) <= self.length class Min(Constraint): """Минимальное значение.""" def __init__(self, value: Union[int, float], message: str = None): self.value = value self.message = message or f"Значение должно быть не меньше {value}" def __call__(self, value: Union[int, float]) -> bool: return value >= self.value class Max(Constraint): """Максимальное значение.""" def __init__(self, value: Union[int, float], message: str = None): self.value = value self.message = message or f"Значение должно быть не больше {value}" def __call__(self, value: Union[int, float]) -> bool: return value <= self.value class Regex(Constraint): """Проверка по регулярному выражению.""" def __init__(self, pattern: str, message: str = None): self.pattern = re.compile(pattern) self.message = message or f"Значение не соответствует формату" def __call__(self, value: str) -> bool: return bool(self.pattern.match(value)) def validate(data: Dict[str, Any], constraints: Dict[str, List[Constraint]]) -> Dict[str, List[str]]: """ Валидирует данные по ограничениям. Args: data: Словарь с данными. constraints: Словарь {поле: [ограничения]}. Returns: Словарь с ошибками {поле: [сообщения]}. """ errors = {} for field, rules in constraints.items(): value = data.get(field) for rule in rules: if not rule(value): errors.setdefault(field, []).append(rule.message) return errors def validate_or_raise(data: Dict[str, Any], constraints: Dict[str, List[Constraint]]) -> None: """ Валидирует данные и выбрасывает ValidationError при ошибках. """ errors = validate(data, constraints) if errors: raise ValidationError(errors) def validate_dto(dto_class: Type, data: Dict[str, Any]) -> Any: """ Валидирует и создаёт DTO (Data Transfer Object) с автоматической валидацией. Ожидается, что класс DTO содержит атрибуты с аннотациями и список constraints. """ # Пока упрощённая версия без авто-валидации DTO # Используем dataclass или pydantic в будущем pass