Source code for joythief.data_structures

import typing as tp
from collections.abc import Hashable, Iterable, Mapping

from .core import Matcher


[docs] class DictContaining(Matcher[Mapping[Hashable, tp.Any]], dict[Hashable, tp.Any]): """Match the specified keys in a mapping, ignoring any extra keys. :param content: mapping or sequence of key-value pairs to include in the comparison :param \\**kwargs: additional key-value pairs to include in the comparison :raises ValueError: if no keys are specified (use :py:class:`~joythief.objects.InstanceOf` with :py:class:`dict` instead). .. code-block:: python assert ( actual == DictContaining([("foo", 123), ("bar", 456)], baz=InstanceOf(int)) ) **Note**: this subclasses :py:class:`dict` so that ``pytest`` will show the common and differing items, e.g.: .. code-block:: python > assert mapping == dict(foo=123, bar=456) E AssertionError: assert DictContaining(**{'foo': 123, 'bar': 0, 'baz': 789}) == {'foo': 123, 'bar': 456} E E Common items: E {'foo': 123} E Differing items: E {'bar': 0} != {'bar': 456} E Left contains 1 more item: E {'baz': 789} # ... """ @tp.overload def __init__(self, /, **kwargs: tp.Any) -> None: ... @tp.overload def __init__( self, content: Mapping[Hashable, tp.Any], /, **kwargs: tp.Any ) -> None: ... @tp.overload def __init__( self, content: Iterable[tuple[Hashable, tp.Any]], /, **kwargs: tp.Any ) -> None: ... def __init__(self, content: tp.Any = None, /, **kwargs: tp.Any) -> None: if not content and not kwargs: raise ValueError("an empty DictContaining matches any mapping") args: tuple[tp.Any, ...] = () if content is None else (content,) super().__init__(*args, **kwargs) def compare(self, other: tp.Any) -> bool: if not isinstance(other, Mapping): return self.not_implemented is_equal: bool = True for key in self: if key not in other or self[key] != other[key]: is_equal = False return is_equal def represent(self) -> str: return f"DictContaining(**{dict.__repr__(self)})"