Fix difflib `?` hint in diff output when dealing with tabs (#15201)
This commit is contained in:
parent
092911d5c0
commit
e1c638da6a
|
@ -733,20 +733,15 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6):
|
||||||
# Strip scores for the best n matches
|
# Strip scores for the best n matches
|
||||||
return [x for score, x in result]
|
return [x for score, x in result]
|
||||||
|
|
||||||
def _count_leading(line, ch):
|
|
||||||
"""
|
|
||||||
Return number of `ch` characters at the start of `line`.
|
|
||||||
|
|
||||||
Example:
|
def _keep_original_ws(s, tag_s):
|
||||||
|
"""Replace whitespace with the original whitespace characters in `s`"""
|
||||||
|
return ''.join(
|
||||||
|
c if tag_c == " " and c.isspace() else tag_c
|
||||||
|
for c, tag_c in zip(s, tag_s)
|
||||||
|
)
|
||||||
|
|
||||||
>>> _count_leading(' abc', ' ')
|
|
||||||
3
|
|
||||||
"""
|
|
||||||
|
|
||||||
i, n = 0, len(line)
|
|
||||||
while i < n and line[i] == ch:
|
|
||||||
i += 1
|
|
||||||
return i
|
|
||||||
|
|
||||||
class Differ:
|
class Differ:
|
||||||
r"""
|
r"""
|
||||||
|
@ -1033,7 +1028,7 @@ class Differ:
|
||||||
|
|
||||||
def _qformat(self, aline, bline, atags, btags):
|
def _qformat(self, aline, bline, atags, btags):
|
||||||
r"""
|
r"""
|
||||||
Format "?" output and deal with leading tabs.
|
Format "?" output and deal with tabs.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -1047,22 +1042,16 @@ class Differ:
|
||||||
'+ \tabcdefGhijkl\n'
|
'+ \tabcdefGhijkl\n'
|
||||||
'? \t ^ ^ ^\n'
|
'? \t ^ ^ ^\n'
|
||||||
"""
|
"""
|
||||||
|
atags = _keep_original_ws(aline, atags).rstrip()
|
||||||
# Can hurt, but will probably help most of the time.
|
btags = _keep_original_ws(bline, btags).rstrip()
|
||||||
common = min(_count_leading(aline, "\t"),
|
|
||||||
_count_leading(bline, "\t"))
|
|
||||||
common = min(common, _count_leading(atags[:common], " "))
|
|
||||||
common = min(common, _count_leading(btags[:common], " "))
|
|
||||||
atags = atags[common:].rstrip()
|
|
||||||
btags = btags[common:].rstrip()
|
|
||||||
|
|
||||||
yield "- " + aline
|
yield "- " + aline
|
||||||
if atags:
|
if atags:
|
||||||
yield "? %s%s\n" % ("\t" * common, atags)
|
yield f"? {atags}\n"
|
||||||
|
|
||||||
yield "+ " + bline
|
yield "+ " + bline
|
||||||
if btags:
|
if btags:
|
||||||
yield "? %s%s\n" % ("\t" * common, btags)
|
yield f"? {btags}\n"
|
||||||
|
|
||||||
# With respect to junk, an earlier version of ndiff simply refused to
|
# With respect to junk, an earlier version of ndiff simply refused to
|
||||||
# *start* a match with a junk element. The result was cases like this:
|
# *start* a match with a junk element. The result was cases like this:
|
||||||
|
|
|
@ -89,10 +89,16 @@ class TestSFbugs(unittest.TestCase):
|
||||||
# Check fix for bug #1488943
|
# Check fix for bug #1488943
|
||||||
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
|
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
|
||||||
self.assertEqual("- \tI am a buggy", diff[0])
|
self.assertEqual("- \tI am a buggy", diff[0])
|
||||||
self.assertEqual("? --\n", diff[1])
|
self.assertEqual("? \t --\n", diff[1])
|
||||||
self.assertEqual("+ \t\tI am a bug", diff[2])
|
self.assertEqual("+ \t\tI am a bug", diff[2])
|
||||||
self.assertEqual("? +\n", diff[3])
|
self.assertEqual("? +\n", diff[3])
|
||||||
|
|
||||||
|
def test_hint_indented_properly_with_tabs(self):
|
||||||
|
diff = list(difflib.Differ().compare(["\t \t \t^"], ["\t \t \t^\n"]))
|
||||||
|
self.assertEqual("- \t \t \t^", diff[0])
|
||||||
|
self.assertEqual("+ \t \t \t^\n", diff[1])
|
||||||
|
self.assertEqual("? \t \t \t +\n", diff[2])
|
||||||
|
|
||||||
def test_mdiff_catch_stop_iteration(self):
|
def test_mdiff_catch_stop_iteration(self):
|
||||||
# Issue #33224
|
# Issue #33224
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix :mod:`difflib` ``?`` hint in diff output when dealing with tabs. Patch
|
||||||
|
by Anthony Sottile.
|
Loading…
Reference in New Issue