|
@@ -1,6 +1,14 @@
|
|
|
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):
|
|
|
"""
|
|
|
Валидация аргумента по типу
|
|
@@ -8,11 +16,35 @@ class validator:
|
|
|
value (any): Передаваемый аргумент
|
|
|
type(Type): Ожидаемый тип
|
|
|
Raises:
|
|
|
- TypeError: Некорректный тип аргумента
|
|
|
+ argument_exception: Некорректный тип аргумента
|
|
|
"""
|
|
|
|
|
|
if not isinstance(value, exp_type):
|
|
|
- raise TypeError(f"Некорректный тип аргумента ({type(value)}, expected {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
|
|
|
|
|
@@ -23,18 +55,18 @@ class validator:
|
|
|
value (any): Передаваемый аргумент
|
|
|
length (int): Ожидаемая длина
|
|
|
Raises:
|
|
|
- ValueError: Несоответствующая длина аргумента
|
|
|
+ argument_exception: Несоответствующая длина аргумента
|
|
|
"""
|
|
|
|
|
|
if isinstance(value, int):
|
|
|
value = str(value)
|
|
|
|
|
|
if len(value) != length:
|
|
|
- raise ValueError(f"Несоответствующая длина аргумента ({len(value)}, expected {length})")
|
|
|
+ raise argument_exception(f"Несоответствующая длина аргумента ({len(value)}, expected {length})")
|
|
|
|
|
|
return True
|
|
|
|
|
|
- def check_length_less(self, value, length: int, inclusive=True):
|
|
|
+ def check_length_less(self, value, length: int, inclusive=False):
|
|
|
"""
|
|
|
Валидация аргумента по максимальной длине
|
|
|
Args:
|
|
@@ -42,7 +74,7 @@ class validator:
|
|
|
length (int): Максимальная допустимая длина
|
|
|
inclusive (bool): Сравнивать включительно? default=True
|
|
|
Raises:
|
|
|
- ValueError: Превышена длина аргумента
|
|
|
+ argument_exception: Превышена длина аргумента
|
|
|
"""
|
|
|
|
|
|
if value is int:
|
|
@@ -50,11 +82,11 @@ class validator:
|
|
|
|
|
|
if (len(value) > length if inclusive \
|
|
|
else len(value) >= length):
|
|
|
- raise ValueError(f"Превышена длина аргумента ({len(value)}, max={length})")
|
|
|
+ raise argument_exception(f"Превышена длина аргумента ({len(value)}, max={length})")
|
|
|
|
|
|
return True
|
|
|
|
|
|
- def check_length_greater(self, value, length: int, inclusive=True):
|
|
|
+ def check_length_greater(self, value, length: int, inclusive=False):
|
|
|
"""
|
|
|
Валидация аргумента по минимальной длине
|
|
|
Args:
|
|
@@ -62,7 +94,7 @@ class validator:
|
|
|
length (int): Максимальная допустимая длина
|
|
|
inclusive (bool): Сравнивать включительно? default=True
|
|
|
Raises:
|
|
|
- ValueError: Недостаточная длина аргумента
|
|
|
+ argument_exception: Недостаточная длина аргумента
|
|
|
"""
|
|
|
|
|
|
if value is int:
|
|
@@ -70,7 +102,7 @@ class validator:
|
|
|
|
|
|
if (len(value) < length if inclusive \
|
|
|
else len(value) <= length):
|
|
|
- raise ValueError("Недостаточная длина аргумента ({len(value)}, min={length})")
|
|
|
+ raise argument_exception("Недостаточная длина аргумента ({len(value)}, min={length})")
|
|
|
|
|
|
return True
|
|
|
|
|
@@ -84,8 +116,8 @@ class validator:
|
|
|
inclusive_min (bool): Сравнимать минимальную длину включительно? default=True
|
|
|
inclusive_max (bool): Сравнивать максимальную длину включительно? default=True
|
|
|
Raises:
|
|
|
- ValueError: Недостаточная длина аргумента
|
|
|
- ValueError: Превышена длина аргумента
|
|
|
+ argument_exception: Недостаточная длина аргумента
|
|
|
+ argument_exception: Превышена длина аргумента
|
|
|
"""
|
|
|
|
|
|
self.check_length_less(value, max_length, inclusive_max)
|
|
@@ -101,8 +133,8 @@ class validator:
|
|
|
exp_type (Type): Ожидаемый тип
|
|
|
length (int): Ожидаемая длина
|
|
|
Raises:
|
|
|
- TypeError: Несоответствие типа аргумента
|
|
|
- ValueError: Несоответствие длины аргумента
|
|
|
+ argument_exception: Несоответствие типа аргумента
|
|
|
+ argument_exception: Несоответствие длины аргумента
|
|
|
"""
|
|
|
|
|
|
self.check_type(value, exp_type)
|
|
@@ -117,10 +149,24 @@ class validator:
|
|
|
value (any): Передаваемый аргумент
|
|
|
expression (str): Регулярное выражение
|
|
|
Raises:
|
|
|
- ValueError: Аргумент не соответствует регулярному выражению
|
|
|
+ argument_exception: Аргумент не соответствует регулярному выражению
|
|
|
"""
|
|
|
|
|
|
if re.match(expression, value) is None:
|
|
|
- raise ValueError(f"Аргумент не соответствует регулярному выражению ({str(value)}, regex: {expression})")
|
|
|
+ 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
|