def assertrepr_compare(config, op: str, left: Any, right: Any) -> Optional[List[str]]: """Return specialised explanations for some operators/operands""" verbose = config.getoption("verbose") if verbose > 1: left_repr = safeformat(left) right_repr = safeformat(right) else: # XXX: "15 chars indentation" is wrong # ("E AssertionError: assert "); should use term width. maxsize = (80 - 15 - len(op) - 2) // 2 # 15 chars indentation, 1 space around op left_repr = saferepr(left, maxsize=maxsize) right_repr = saferepr(right, maxsize=maxsize) summary = "{} {} {}".format(left_repr, op, right_repr) explanation = None try: if op == "==": if istext(left) and istext(right): explanation = _diff_text(left, right, verbose) else: if 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)): type_fn = (isdatacls, isattrs) explanation = _compare_eq_cls(left, right, verbose, type_fn) elif verbose > 0: explanation = _compare_eq_verbose(left, right) if isiterable(left) and isiterable(right): expl = _compare_eq_iterable(left, right, verbose) if explanation is not None: explanation.extend(expl) else: explanation = expl elif op == "not in": if istext(left) and istext(right): explanation = _notin_text(left, right, verbose) except outcomes.Exit: raise except Exception: explanation = [ "(pytest_assertion plugin: representation of details failed. " "Probably an object has a faulty __repr__.)", str(_pytest._code.ExceptionInfo.from_current()), ] if not explanation: return None return [summary] + explanation
def repr_locals(self, locals: Mapping[str, object]) -> Optional["ReprLocals"]: if self.showlocals: lines = [] keys = [loc for loc in locals if loc[0] != "@"] keys.sort() for name in keys: value = locals[name] if name == "__builtins__": lines.append("__builtins__ = <builtins>") else: # This formatting could all be handled by the # _repr() function, which is only reprlib.Repr in # disguise, so is very configurable. if self.truncate_locals: str_repr = saferepr(value) else: str_repr = safeformat(value) # if len(str_repr) < 70 or not isinstance(value, (list, tuple, dict)): lines.append(f"{name:<10} = {str_repr}") # else: # self._line("%-10s =\\" % (name,)) # # XXX # pprint.pprint(value, stream=self.excinfowriter) return ReprLocals(lines) return None
def assertrepr_compare(config, op: str, left: Any, right: Any) -> Optional[List[str]]: """Return specialised explanations for some operators/operands""" verbose = config.getoption("verbose") if verbose > 1: left_repr = safeformat(left) right_repr = safeformat(right) else: # XXX: "15 chars indentation" is wrong # ("E AssertionError: assert "); should use term width. maxsize = ( 80 - 15 - len(op) - 2 ) // 2 # 15 chars indentation, 1 space around op left_repr = saferepr(left, maxsize=maxsize) right_repr = saferepr(right, maxsize=maxsize) summary = "{} {} {}".format(left_repr, op, right_repr) explanation = None try: if op == "==": explanation = _compare_eq_any(left, right, verbose) elif op == "not in": if istext(left) and istext(right): explanation = _notin_text(left, right, verbose) except outcomes.Exit: raise except Exception: explanation = [ "(pytest_assertion plugin: representation of details failed: {}.".format( _pytest._code.ExceptionInfo.from_current()._getreprcrash() ), " Probably an object has a faulty __repr__.)", ] if not explanation: return None return [summary] + explanation