validator.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import re
  2. from numbers import Number
  3. from src.errors.argument_exception import argument_exception
  4. class validator:
  5. # Singleton
  6. def __new__(cls):
  7. if not hasattr(cls, "instance"):
  8. cls.instance = super(validator, cls).__new__(cls)
  9. return cls.instance
  10. def check_type(self, value, exp_type):
  11. """
  12. Валидация аргумента по типу
  13. Args:
  14. value (any): Передаваемый аргумент
  15. type(Type): Ожидаемый тип
  16. Raises:
  17. argument_exception: Некорректный тип аргумента
  18. """
  19. if not isinstance(value, exp_type):
  20. raise argument_exception(f"Некорректный тип аргумента ({type(value)}, expected {exp_type})")
  21. return True
  22. def check_type_any(self, value, *types):
  23. """
  24. Валидация аргумента по соответствию одному из типов
  25. Args:
  26. value (any): Передаваемый аргумент
  27. *types (Type): Ожидаемые типы
  28. Raises:
  29. argument_exception: Аргумент не соответствует ни одному из ожидаемых типов
  30. """
  31. flag = False
  32. for t in types:
  33. if t is None:
  34. t = type(None)
  35. if isinstance(value, t):
  36. flag = True
  37. break
  38. if not flag:
  39. raise argument_exception("Аргумент не соответствует ни одному из ожидаемых типов "\
  40. + f"({type(value)}, expected={', '.join(types)})")
  41. return True
  42. def check_length(self, value, length: int):
  43. """
  44. Валидация аргумента по длине
  45. Args:
  46. value (any): Передаваемый аргумент
  47. length (int): Ожидаемая длина
  48. Raises:
  49. argument_exception: Несоответствующая длина аргумента
  50. """
  51. if isinstance(value, int):
  52. value = str(value)
  53. if len(value) != length:
  54. raise argument_exception(f"Несоответствующая длина аргумента ({len(value)}, expected {length})")
  55. return True
  56. def check_length_less(self, value, length: int, inclusive=False):
  57. """
  58. Валидация аргумента по максимальной длине
  59. Args:
  60. value (any): Передаваемый аргумент
  61. length (int): Максимальная допустимая длина
  62. inclusive (bool): Сравнивать включительно? default=True
  63. Raises:
  64. argument_exception: Превышена длина аргумента
  65. """
  66. if value is int:
  67. value = str(value)
  68. if (len(value) > length if inclusive \
  69. else len(value) >= length):
  70. raise argument_exception(f"Превышена длина аргумента ({len(value)}, max={length})")
  71. return True
  72. def check_length_greater(self, value, length: int, inclusive=False):
  73. """
  74. Валидация аргумента по минимальной длине
  75. Args:
  76. value (any): Передаваемый аргумент
  77. length (int): Максимальная допустимая длина
  78. inclusive (bool): Сравнивать включительно? default=True
  79. Raises:
  80. argument_exception: Недостаточная длина аргумента
  81. """
  82. if value is int:
  83. value = str(value)
  84. if (len(value) < length if inclusive \
  85. else len(value) <= length):
  86. raise argument_exception("Недостаточная длина аргумента ({len(value)}, min={length})")
  87. return True
  88. def check_length_bound(self, value, min_length: int, max_length: int, inclusive_min=True, inclusive_max=True):
  89. """
  90. Валидация аргумента по минимальной и максимальной длинам
  91. Args:
  92. value (any): Передаваемый аргумент
  93. min_length (int): Минимальная длина
  94. max_length (int): Максимальная длина
  95. inclusive_min (bool): Сравнимать минимальную длину включительно? default=True
  96. inclusive_max (bool): Сравнивать максимальную длину включительно? default=True
  97. Raises:
  98. argument_exception: Недостаточная длина аргумента
  99. argument_exception: Превышена длина аргумента
  100. """
  101. self.check_length_less(value, max_length, inclusive_max)
  102. self.check_length_greater(value, min_length, inclusive_min)
  103. return True
  104. def check_type_length(self, value, exp_type, length: int):
  105. """
  106. Валидация аргумента по типу и длине
  107. Args:
  108. value (any): Передаваемый аргумент
  109. exp_type (Type): Ожидаемый тип
  110. length (int): Ожидаемая длина
  111. Raises:
  112. argument_exception: Несоответствие типа аргумента
  113. argument_exception: Несоответствие длины аргумента
  114. """
  115. self.check_type(value, exp_type)
  116. self.check_length(value, length)
  117. return True
  118. def check_regex(self, value, expression: str):
  119. """
  120. Валидация аргумента по регулярному выражению
  121. Args:
  122. value (any): Передаваемый аргумент
  123. expression (str): Регулярное выражение
  124. Raises:
  125. argument_exception: Аргумент не соответствует регулярному выражению
  126. """
  127. if re.match(expression, value) is None:
  128. raise argument_exception(f"Аргумент не соответствует регулярному выражению ({str(value)}, regex: {expression})")
  129. return True
  130. def check_number(self, value):
  131. """
  132. Валидация аргумента по соответствию типу Число
  133. Args:
  134. value: Передаваемый аргумент
  135. Raises:
  136. argument_exception: Аргумент не является числом
  137. """
  138. if not isinstance(value, Number):
  139. raise argument_exception(f"Аргумент не является числом (type={type(value)})")
  140. return True