import re from numbers import Number from src.errors.argument_exception import argument_exception class validator: # Singleton def __new__(cls): if not hasattr(cls, "instance"): cls.instance = super(validator, cls).__new__(cls) return cls.instance def check_type(self, value, exp_type): """ Валидация аргумента по типу Args: value (any): Передаваемый аргумент type(Type): Ожидаемый тип Raises: argument_exception: Некорректный тип аргумента """ if not isinstance(value, exp_type): raise argument_exception(f"Некорректный тип аргумента ({type(value)}, expected {exp_type})") return True def check_type_any(self, value, *types): """ Валидация аргумента по соответствию одному из типов Args: value (any): Передаваемый аргумент *types (Type): Ожидаемые типы Raises: argument_exception: Аргумент не соответствует ни одному из ожидаемых типов """ flag = False for t in types: if t is None: t = type(None) if isinstance(value, t): flag = True break if not flag: raise argument_exception("Аргумент не соответствует ни одному из ожидаемых типов "\ + f"({type(value)}, expected={', '.join(types)})") return True def check_length(self, value, length: int): """ Валидация аргумента по длине Args: value (any): Передаваемый аргумент length (int): Ожидаемая длина Raises: argument_exception: Несоответствующая длина аргумента """ if isinstance(value, int): value = str(value) if len(value) != length: raise argument_exception(f"Несоответствующая длина аргумента ({len(value)}, expected {length})") return True def check_length_less(self, value, length: int, inclusive=False): """ Валидация аргумента по максимальной длине Args: value (any): Передаваемый аргумент length (int): Максимальная допустимая длина inclusive (bool): Сравнивать включительно? default=True Raises: argument_exception: Превышена длина аргумента """ if value is int: value = str(value) if (len(value) > length if inclusive \ else len(value) >= length): raise argument_exception(f"Превышена длина аргумента ({len(value)}, max={length})") return True def check_length_greater(self, value, length: int, inclusive=False): """ Валидация аргумента по минимальной длине Args: value (any): Передаваемый аргумент length (int): Максимальная допустимая длина inclusive (bool): Сравнивать включительно? default=True Raises: argument_exception: Недостаточная длина аргумента """ if value is int: value = str(value) if (len(value) < length if inclusive \ else len(value) <= length): raise argument_exception("Недостаточная длина аргумента ({len(value)}, min={length})") return True def check_length_bound(self, value, min_length: int, max_length: int, inclusive_min=True, inclusive_max=True): """ Валидация аргумента по минимальной и максимальной длинам Args: value (any): Передаваемый аргумент min_length (int): Минимальная длина max_length (int): Максимальная длина inclusive_min (bool): Сравнимать минимальную длину включительно? default=True inclusive_max (bool): Сравнивать максимальную длину включительно? default=True Raises: argument_exception: Недостаточная длина аргумента argument_exception: Превышена длина аргумента """ self.check_length_less(value, max_length, inclusive_max) self.check_length_greater(value, min_length, inclusive_min) return True def check_type_length(self, value, exp_type, length: int): """ Валидация аргумента по типу и длине Args: value (any): Передаваемый аргумент exp_type (Type): Ожидаемый тип length (int): Ожидаемая длина Raises: argument_exception: Несоответствие типа аргумента argument_exception: Несоответствие длины аргумента """ self.check_type(value, exp_type) self.check_length(value, length) return True def check_regex(self, value, expression: str): """ Валидация аргумента по регулярному выражению Args: value (any): Передаваемый аргумент expression (str): Регулярное выражение Raises: argument_exception: Аргумент не соответствует регулярному выражению """ if re.match(expression, value) is None: raise argument_exception(f"Аргумент не соответствует регулярному выражению ({str(value)}, regex: {expression})") return True def check_number(self, value): """ Валидация аргумента по соответствию типу Число Args: value: Передаваемый аргумент Raises: argument_exception: Аргумент не является числом """ if not isinstance(value, Number): raise argument_exception(f"Аргумент не является числом (type={type(value)})") return True