-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy path_compare_sequence.py
More file actions
95 lines (83 loc) · 3.15 KB
/
Copy path_compare_sequence.py
File metadata and controls
95 lines (83 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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._diff import ndiff_too_slow_for_lines
from _pytest.assertion._diff import truncated_ndiff
from _pytest.assertion._typing import _HighlightFunc
from _pytest.compat import running_on_ci
def _compare_eq_iterable(
left: Iterable[object],
right: Iterable[object],
highlighter: _HighlightFunc,
verbose: int = 0,
) -> 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
left_formatting = PrettyPrinter().pformat(left).splitlines()
right_formatting = PrettyPrinter().pformat(right).splitlines()
yield ""
yield "Full diff:"
if ndiff_too_slow_for_lines(left_formatting, right_formatting):
yield from truncated_ndiff(left_formatting, right_formatting, highlighter)
return
# "right" is the expected base against which we compare "left",
# see https://github.com/pytest-dev/pytest/issues/3333
yield from highlighter(
"\n".join(
line.rstrip() for line in difflib.ndiff(right_formatting, left_formatting)
),
lexer="diff",
).splitlines()
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)}"