diff options
author | Karthikeyan Singaravelan <tir.karthi@gmail.com> | 2020-07-28 12:24:24 +0000 |
---|---|---|
committer | Ran Benita <ran@unusedvar.com> | 2020-10-31 14:41:53 +0200 |
commit | 9a0f4e57ee6ec0602e2f5e6e53920bb1d985e316 (patch) | |
tree | 52f9029d11846215e2d5efd32dd34ec68dfbf570 /src/_pytest/assertion | |
parent | 5913cd20ec7c3f0a8305aa072110da5c896fddb8 (diff) | |
download | pytest-9a0f4e57ee6ec0602e2f5e6e53920bb1d985e316.tar.gz |
Add support to display field names in namedtuple diffs.
Diffstat (limited to 'src/_pytest/assertion')
-rw-r--r-- | src/_pytest/assertion/util.py | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 93fa48b8e..da1ffd15e 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -110,6 +110,10 @@ def isset(x: Any) -> bool: return isinstance(x, (set, frozenset)) +def isnamedtuple(obj: Any) -> bool: + return isinstance(obj, tuple) and getattr(obj, "_fields", None) is not None + + def isdatacls(obj: Any) -> bool: return getattr(obj, "__dataclass_fields__", None) is not None @@ -171,14 +175,20 @@ def _compare_eq_any(left: Any, right: Any, verbose: int = 0) -> List[str]: if istext(left) and istext(right): explanation = _diff_text(left, right, verbose) else: - if issequence(left) and issequence(right): + if type(left) == type(right) and ( + isdatacls(left) or isattrs(left) or isnamedtuple(left) + ): + # Note: unlike dataclasses/attrs, namedtuples compare only the + # field values, not the type or field names. But this branch + # intentionally only handles the same-type case, which was often + # used in older code bases before dataclasses/attrs were available. + explanation = _compare_eq_cls(left, right, verbose) + elif issequence(left) and issequence(right): explanation = _compare_eq_sequence(left, right, verbose) elif isset(left) and isset(right): explanation = _compare_eq_set(left, right, verbose) elif isdict(left) and isdict(right): explanation = _compare_eq_dict(left, right, verbose) - elif type(left) == type(right) and (isdatacls(left) or isattrs(left)): - explanation = _compare_eq_cls(left, right, verbose) elif verbose > 0: explanation = _compare_eq_verbose(left, right) if isiterable(left) and isiterable(right): @@ -408,6 +418,10 @@ def _compare_eq_cls(left: Any, right: Any, verbose: int) -> List[str]: elif isattrs(left): all_fields = left.__attrs_attrs__ fields_to_check = [field.name for field in all_fields if getattr(field, "eq")] + elif isnamedtuple(left): + fields_to_check = left._fields + else: + assert False indent = " " same = [] |