Исходный код EJIO.utils.component.check.type_checker
## /utils/check/type_checker.py
from collections.abc import Callable
from typing import ClassVar
from ...interface import StaticClass
from .type_checker_types import TypeCheckerTypes
__all__ = [
'TypeCheckerClass',
]
[документация]
class TypeCheckerClass[V, S: TypeCheckerTypes](StaticClass):
"""
Абстрактный класс, предоставляющий базовый интерфейс и логику
для классов, осуществляющих проверку типов данных и структур.
V: Тип проверяемого значения (например, Any или str).
S: Тип флага.
"""
__slots__ = ()
# Словарь: флаг -> функция проверки
_type_checks: ClassVar[dict[S, Callable[[V], bool]]] = {} #type: ignore
[документация]
@classmethod
def get_types(cls, value: V) -> S:
"""
Определяет, к каким типам принадлежит переданное значение.
Возвращает комбинацию флагов, описывающих все подходящие типы.
:param value: Значение, типы которого нужно определить.
:return: Комбинация флагов типа S.
"""
#result_flags: S = S.NONE
result_flags: S = next(iter(cls._type_checks.keys())) #type: ignore
result_flags = result_flags ^ result_flags # Гарантированный 0 (аналог S.NONE)
for flag, check_fn in cls._type_checks.items(): #type: ignore
if check_fn(value):
result_flags |= flag # Объединение флагов битовым ИЛИ
return result_flags
[документация]
@classmethod
def check_types(cls, value: V, flags: S) -> bool:
"""
Проверяет, соответствует ли значение хотя бы одному из переданных флагов.
:param value: Значение, которое нужно проверить.
:param flags: Комбинация флагов типов для проверки.
:return: True, если значение соответствует хотя бы одному флагу, иначе False.
"""
for flag, check_fn in cls._type_checks.items(): #type: ignore
if flags & flag and check_fn(value):
return True
return False
[документация]
@classmethod
def check_types_strict(cls, value: V, flags: S) -> bool:
"""
Проверяет, что значение абсолютно полностью соответствует всем переданным флагам.
:param value: Значение, которое нужно проверить.
:param flags: Комбинация флагов типов, которой должно удовлетворять значение.
:return: True, если значение прошло все проверки для указанных флагов, иначе False.
"""
for flag, check_fn in cls._type_checks.items(): #type: ignore
# Пропускаем флаг NONE, он не применяется к проверкам
#if flag == S.NONE:
if flag.value == 0:
continue
# Если флаг есть в переданных, должна пройти проверка
if flags & flag:
# Если проверка отсутствует или не пройдена
if check_fn is None or not check_fn(value):
return False
return True