# Path: typepy/checker/_checker.py
# class CheckerFactory:
#     __slots__ = ("__min_strict_level", "__max_strict_level", "__checker_mapping")
# 
#     @property
#     def min_strict_level(self):
#         return self.__min_strict_level
# 
#     @property
#     def max_strict_level(self):
#         return self.__max_strict_level
# 
#     def __init__(self, checker_mapping):
#         self.__checker_mapping = checker_mapping
# 
#         self.__min_strict_level = min(checker_mapping)
#         self.__max_strict_level = max(checker_mapping)
#         self.__checker_mapping[None] = self.__max_strict_level
# 
#     def get_checker_class(self, strict_level=None):
#         checker_class = self.__checker_mapping.get(strict_level)
#         if checker_class:
#             return checker_class
#         if strict_level < self.min_strict_level:
#             return self.__checker_mapping[self.min_strict_level]
#         if strict_level > self.max_strict_level:
#             return self.__checker_mapping[self.max_strict_level]
# 
#         raise ValueError(f"unexpected strict level: {strict_level}")
# 
# class TypeCheckerBase(TypeCheckerInterface):
#     __slots__ = ("_value",)
# 
#     def __init__(self, value):
#         self._value = value
# 
#     @abc.abstractmethod
#     def is_instance(self):
#         pass
# 
#     def is_type(self) -> bool:
#         return self.is_instance() and not self.is_exclude_instance()
# 
#     def validate(self) -> None:
#         """
#         :raises TypeError:
#             If the value is not matched the type to be expected.
#         """
# 
#         if self.is_type():
#             return
# 
#         raise TypeError(f"invalid value type: actual={type(self._value)}")
# 
#     def is_exclude_instance(self):
#         return False
# 
#     def is_valid_after_convert(self, converted_value):
#         return True
# 
# class TypeCheckerDelegator(TypeCheckerInterface):
#     __slots__ = ("__checker",)
# 
#     def __init__(self, value, checker_factory, strict_level):
#         self.__checker = checker_factory.get_checker_class(strict_level)(value)
# 
#     def is_type(self) -> bool:
#         return self.__checker.is_type()
# 
#     def is_valid_after_convert(self, value):
#         return self.__checker.is_valid_after_convert(value)
# 
#     def is_instance(self):
#         return self.__checker.is_instance()
# 
#     def is_exclude_instance(self):
#         return self.__checker.is_exclude_instance()
# 
#     def validate(self) -> None:
#         self.__checker.validate()
# 
# Path: typepy/checker/_common.py
# def isstring(value):
#     return isinstance(value, (str,) + (str, bytes))


from ._checker import CheckerFactory, TypeCheckerBase, TypeCheckerDelegator
from ._common import isstring
        import ipaddress
"""
.. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
"""



class IpAddressTypeCheckerStrictLevel0(TypeCheckerBase):
    def is_instance(self):
        return self._is_ipaddress(self._value)

    def is_valid_after_convert(self, converted_value):
        return self._is_ipaddress(converted_value)

    @staticmethod
    def _is_ipaddress(value):

        return isinstance(value, (ipaddress.IPv4Address, ipaddress.IPv6Address))


class IpAddressTypeCheckerStrictLevel1(IpAddressTypeCheckerStrictLevel0):
    def is_exclude_instance(self):
        return isstring(self._value) or super().is_exclude_instance()



# Path: typepy/checker/_checker.py
# class CheckerFactory:
#     __slots__ = ("__min_strict_level", "__max_strict_level", "__checker_mapping")
# 
#     @property
#     def min_strict_level(self):
#         return self.__min_strict_level
# 
#     @property
#     def max_strict_level(self):
#         return self.__max_strict_level
# 
#     def __init__(self, checker_mapping):
#         self.__checker_mapping = checker_mapping
# 
#         self.__min_strict_level = min(checker_mapping)
#         self.__max_strict_level = max(checker_mapping)
#         self.__checker_mapping[None] = self.__max_strict_level
# 
#     def get_checker_class(self, strict_level=None):
#         checker_class = self.__checker_mapping.get(strict_level)
#         if checker_class:
#             return checker_class
#         if strict_level < self.min_strict_level:
#             return self.__checker_mapping[self.min_strict_level]
#         if strict_level > self.max_strict_level:
#             return self.__checker_mapping[self.max_strict_level]
# 
#         raise ValueError(f"unexpected strict level: {strict_level}")
# 
# class TypeCheckerBase(TypeCheckerInterface):
#     __slots__ = ("_value",)
# 
#     def __init__(self, value):
#         self._value = value
# 
#     @abc.abstractmethod
#     def is_instance(self):
#         pass
# 
#     def is_type(self) -> bool:
#         return self.is_instance() and not self.is_exclude_instance()
# 
#     def validate(self) -> None:
#         """
#         :raises TypeError:
#             If the value is not matched the type to be expected.
#         """
# 
#         if self.is_type():
#             return
# 
#         raise TypeError(f"invalid value type: actual={type(self._value)}")
# 
#     def is_exclude_instance(self):
#         return False
# 
#     def is_valid_after_convert(self, converted_value):
#         return True
# 
# class TypeCheckerDelegator(TypeCheckerInterface):
#     __slots__ = ("__checker",)
# 
#     def __init__(self, value, checker_factory, strict_level):
#         self.__checker = checker_factory.get_checker_class(strict_level)(value)
# 
#     def is_type(self) -> bool:
#         return self.__checker.is_type()
# 
#     def is_valid_after_convert(self, value):
#         return self.__checker.is_valid_after_convert(value)
# 
#     def is_instance(self):
#         return self.__checker.is_instance()
# 
#     def is_exclude_instance(self):
#         return self.__checker.is_exclude_instance()
# 
#     def validate(self) -> None:
#         self.__checker.validate()
# 
# Path: typepy/checker/_common.py
# def isstring(value):
#     return isinstance(value, (str,) + (str, bytes))


# Path: typepy/checker/_ipaddress.py
from ._checker import CheckerFactory, TypeCheckerBase, TypeCheckerDelegator
from ._common import isstring
        import ipaddress

"""
.. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
"""



class IpAddressTypeCheckerStrictLevel0(TypeCheckerBase):
    def is_instance(self):
        return self._is_ipaddress(self._value)

    def is_valid_after_convert(self, converted_value):
        return self._is_ipaddress(converted_value)

    @staticmethod
    def _is_ipaddress(value):

        return isinstance(value, (ipaddress.IPv4Address, ipaddress.IPv6Address))


class IpAddressTypeCheckerStrictLevel1(IpAddressTypeCheckerStrictLevel0):
    def is_exclude_instance(self):
        return isstring(self._value) or super().is_exclude_instance()



_factory = CheckerFactory(