Source code for joythief.compound

import typing as tp
import warnings
from abc import ABC

from .core import Matcher

T = tp.TypeVar("T")


[docs] class PointlessCompound(UserWarning): """Emitted if you create a compound matcher with a single child matcher.""" MESSAGE: tp.ClassVar[str] = ( "a compound matcher with a single child matcher can be trivially replaced by that child" )
[docs] class ZeroMatchers(TypeError): """Thrown if you try to create a compound matcher with no child matchers.""" MESSAGE: tp.ClassVar[str] = "compound matchers require at least one child matcher" def __init__(self) -> None: super().__init__(self.MESSAGE)
class _Compound(Matcher[T], tp.Generic[T], ABC): _matchers: tuple[Matcher[T], ...] def __init__(self, *matchers: Matcher[T]): if not matchers: raise ZeroMatchers if len(matchers) == 1: warnings.warn(PointlessCompound.MESSAGE, PointlessCompound, stacklevel=2) super().__init__() self._matchers = matchers def represent(self) -> str: return f"{type(self).__name__}({', '.join(repr(m) for m in self._matchers)})"
[docs] class AllOf(_Compound[T]): """Matches values which match all of the child matchers. .. note:: Unlike :py:func:`all` this comparison is not lazy; all matchers are compared, whether or not any are unequal. """ def compare(self, other: tp.Any) -> bool: equal: bool = True for matcher in self._matchers: if matcher != other: equal = False return equal
[docs] class AnyOf(_Compound[T]): """Matches values which match any of the child matchers. .. note:: Unlike :py:func:`any` this comparison is not lazy; all matchers are compared, whether or not any are equal. """ def compare(self, other: tp.Any) -> bool: equal: bool = False for matcher in self._matchers: if matcher == other: equal = True return equal