Yield specialised explanations for some operators/operands. The first line yielded is always the summary (``left op right``); subsequent lines are the detailed explanation. Yields nothing when no specialised explanation applies, which lets consumers map an empty iterator to "no expl
(
op: str,
left: object,
right: object,
*,
verbose: int,
highlighter: _HighlightFunc,
assertion_text_diff_style: _AssertionTextDiffStyle,
)
| 133 | |
| 134 | |
| 135 | def assertrepr_compare( |
| 136 | op: str, |
| 137 | left: object, |
| 138 | right: object, |
| 139 | *, |
| 140 | verbose: int, |
| 141 | highlighter: _HighlightFunc, |
| 142 | assertion_text_diff_style: _AssertionTextDiffStyle, |
| 143 | ) -> Iterator[str]: |
| 144 | """Yield specialised explanations for some operators/operands. |
| 145 | |
| 146 | The first line yielded is always the summary (``left op right``); |
| 147 | subsequent lines are the detailed explanation. Yields nothing when no |
| 148 | specialised explanation applies, which lets consumers map an empty |
| 149 | iterator to "no explanation" without materialising anything. |
| 150 | |
| 151 | The iterator is lazy on purpose: a streaming consumer can stop pulling |
| 152 | lines as soon as it has enough to show, so an enormous diff doesn't |
| 153 | have to be built in full just to be thrown away. |
| 154 | """ |
| 155 | # Strings which normalize equal are often hard to distinguish when printed; use ascii() to make this easier. |
| 156 | # See issue #3246. |
| 157 | use_ascii = ( |
| 158 | isinstance(left, str) |
| 159 | and isinstance(right, str) |
| 160 | and normalize("NFD", left) == normalize("NFD", right) |
| 161 | ) |
| 162 | |
| 163 | if verbose > 1: |
| 164 | left_repr = saferepr_unlimited(left, use_ascii=use_ascii) |
| 165 | right_repr = saferepr_unlimited(right, use_ascii=use_ascii) |
| 166 | else: |
| 167 | # XXX: "15 chars indentation" is wrong |
| 168 | # ("E AssertionError: assert "); should use term width. |
| 169 | maxsize = ( |
| 170 | 80 - 15 - len(op) - 2 |
| 171 | ) // 2 # 15 chars indentation, 1 space around op |
| 172 | |
| 173 | left_repr = saferepr(left, maxsize=maxsize, use_ascii=use_ascii) |
| 174 | right_repr = saferepr(right, maxsize=maxsize, use_ascii=use_ascii) |
| 175 | |
| 176 | summary = f"{left_repr} {op} {right_repr}" |
| 177 | |
| 178 | try: |
| 179 | if op == "==": |
| 180 | source = _compare_eq_any( |
| 181 | left, |
| 182 | right, |
| 183 | highlighter, |
| 184 | verbose, |
| 185 | assertion_text_diff_style, |
| 186 | ) |
| 187 | elif op == "not in" and istext(left) and istext(right): |
| 188 | source = _notin_text(left, right, verbose) |
| 189 | elif op in {"!=", ">=", "<=", ">", "<"} and isset(left) and isset(right): |
| 190 | source = SET_COMPARISON_FUNCTIONS[op](left, right, highlighter, verbose) |
| 191 | else: |
| 192 | source = iter(()) |
nothing calls this directly
no test coverage detected