/
niceSOFT
/
python3-pytest
Обзор
Документация
Войти
/
niceSOFT
/
python3-pytest
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/_pytest/assertion/_compare_sequence.py
96 строк
4 KB
Pierre Sassoulas
[perf] Cap all comparison formatting by the truncation budget
27 июл 2026, 22:36
27 июл 2026, 22:36
fbdae4e
Код
Авторство
О чём код?
from __future__ import annotations from collections.abc import Iterable from collections.abc import Iterator from collections.abc import Sequence from _pytest._io.pprint import PrettyPrinter from _pytest._io.saferepr import saferepr from _pytest.assertion._typing import _HighlightFunc from _pytest.assertion._typing import NO_TRUNCATION_BUDGET from _pytest.assertion._typing import TruncationBudget from _pytest.compat import running_on_ci def _compare_eq_iterable( left: Iterable[object], right: Iterable[object], highlighter: _HighlightFunc, verbose: int = 0, truncation_budget: TruncationBudget = NO_TRUNCATION_BUDGET, ) -> Iterator[str]: if verbose <= 0 and not running_on_ci(): yield "Use -v to get more diff" return # dynamic import to speedup pytest import difflib pp = PrettyPrinter() # ``pformat_lines`` spells an unbounded dimension ``None``; the budget spells it ``0``. max_lines = truncation_budget.max_lines or None max_chars = truncation_budget.max_chars or None left_formatting = pp.pformat_lines(left, max_lines=max_lines, max_chars=max_chars) right_formatting = pp.pformat_lines(right, max_lines=max_lines, max_chars=max_chars) yield "" yield "Full diff: (-: missing in left side, +: extra in left side)" # "right" is the expected base against which we compare "left", # see https://github.com/pytest-dev/pytest/issues/3333 # Highlight each ndiff line individually so the streaming truncator can # stop pulling from ``difflib.ndiff`` once its budget is full; the diff # lexer is line-oriented, so per-line highlighting is equivalent. for line in difflib.ndiff(right_formatting, left_formatting): yield highlighter(line.rstrip(), lexer="diff") def _compare_eq_sequence( left: Sequence[object], right: Sequence[object], highlighter: _HighlightFunc, verbose: int = 0, ) -> Iterator[str]: comparing_bytes = isinstance(left, bytes) and isinstance(right, bytes) len_left = len(left) len_right = len(right) for i in range(min(len_left, len_right)): if left[i] != right[i]: if comparing_bytes: # when comparing bytes, we want to see their ascii representation # instead of their numeric values (#5260) # using a slice gives us the ascii representation: # >>> s = b'foo' # >>> s[0] # 102 # >>> s[0:1] # b'f' left_value: object = left[i : i + 1] right_value: object = right[i : i + 1] else: left_value = left[i] right_value = right[i] yield ( f"At index {i} diff:" f" {highlighter(repr(left_value))} != {highlighter(repr(right_value))}" ) break if comparing_bytes: # when comparing bytes, it doesn't help to show the "sides contain one or more # items" longer explanation, so skip it return len_diff = len_left - len_right if len_diff: if len_diff > 0: dir_with_more = "Left" extra = saferepr(left[len_right]) else: len_diff = 0 - len_diff dir_with_more = "Right" extra = saferepr(right[len_left]) if len_diff == 1: yield f"{dir_with_more} contains one more item: {highlighter(extra)}" else: yield f"{dir_with_more} contains {len_diff} more items, first extra item: {highlighter(extra)}"