Add dict and object.__init__ comparison utilities with tests

This commit is contained in:
thatmattlove 2021-09-17 18:12:37 -07:00
parent ed58c3622b
commit af0d5345bf
2 changed files with 83 additions and 0 deletions

View file

@ -334,3 +334,31 @@ def at_least(minimum: int, value: int,) -> int:
if value < minimum:
return minimum
return value
def compare_dicts(dict_a: t.Dict[t.Any, t.Any], dict_b: t.Dict[t.Any, t.Any]) -> bool:
"""Determine if two dictationaries are (mostly) equal."""
if isinstance(dict_a, t.Dict) and isinstance(dict_b, t.Dict):
dict_a_keys, dict_a_values = set(dict_a.keys()), set(dict_a.values())
dict_b_keys, dict_b_values = set(dict_b.keys()), set(dict_b.values())
return all((dict_a_keys == dict_b_keys, dict_a_values == dict_b_values))
return False
def compare_init(obj_a: object, obj_b: object) -> bool:
"""Compare the `__init__` annoations of two objects."""
def _check_obj(obj: object):
"""Ensure `__annotations__` exists on the `__init__` method."""
if hasattr(obj, "__init__") and isinstance(getattr(obj, "__init__", None), t.Callable):
if hasattr(obj.__init__, "__annotations__") and isinstance(
getattr(obj.__init__, "__annotations__", None), t.Dict
):
return True
return False
if all((_check_obj(obj_a), _check_obj(obj_b))):
obj_a.__init__.__annotations__.pop("self", None)
obj_b.__init__.__annotations__.pop("self", None)
return compare_dicts(obj_a.__init__.__annotations__, obj_b.__init__.__annotations__)
return False

View file

@ -0,0 +1,55 @@
"""Test generic utilities."""
# Local
from .. import compare_init, compare_dicts
def test_compare_dicts():
d1 = {"one": 1, "two": 2}
d2 = {"one": 1, "two": 2}
d3 = {"one": 1, "three": 3}
d4 = {"one": 1, "two": 3}
d5 = {}
d6 = {}
checks = (
(d1, d2, True),
(d1, d3, False),
(d1, d4, False),
(d1, d1, True),
(d5, d6, True),
(d1, [], False),
)
for a, b, expected in checks:
assert compare_dicts(a, b) is expected
def test_compare_init():
class Compare1:
def __init__(self, item: str) -> None:
pass
class Compare2:
def __init__(self: "Compare2", item: str) -> None:
pass
class Compare3:
def __init__(self: "Compare3", item: str, other_item: int) -> None:
pass
class Compare4:
def __init__(self: "Compare4", item: bool) -> None:
pass
class Compare5:
pass
checks = (
(Compare1, Compare2, True),
(Compare1, Compare3, False),
(Compare1, Compare4, False),
(Compare1, Compare5, False),
(Compare1, Compare1, True),
)
for a, b, expected in checks:
assert compare_init(a, b) is expected