Skip to content

Commit 44debb1

Browse files
committed
Speed up difflib._mdiff() for lopsided replacements
1 parent ed1aa1f commit 44debb1

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

Lib/difflib.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
'unified_diff', 'diff_bytes', 'HtmlDiff', 'Match']
3232

3333
from heapq import nlargest as _nlargest
34-
from collections import namedtuple as _namedtuple
34+
from collections import deque as _deque, namedtuple as _namedtuple
3535
from types import GenericAlias
3636
lazy from _colorize import can_colorize, get_theme
3737

@@ -1558,7 +1558,7 @@ def _line_pair_iterator():
15581558
is defined) does not need to be of module scope.
15591559
"""
15601560
line_iterator = _line_iterator()
1561-
fromlines,tolines=[],[]
1561+
fromlines, tolines = _deque(), _deque()
15621562
while True:
15631563
# Collecting lines of text until we have a from/to pair
15641564
while (len(fromlines)==0 or len(tolines)==0):
@@ -1571,8 +1571,8 @@ def _line_pair_iterator():
15711571
if to_line is not None:
15721572
tolines.append((to_line,found_diff))
15731573
# Once we have a pair, remove them from the collection and yield it
1574-
from_line, fromDiff = fromlines.pop(0)
1575-
to_line, to_diff = tolines.pop(0)
1574+
from_line, fromDiff = fromlines.popleft()
1575+
to_line, to_diff = tolines.popleft()
15761576
yield (from_line,to_line,fromDiff or to_diff)
15771577

15781578
# Handle case where user does not want context differencing, just yield

Lib/test/test_difflib.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ def test_mdiff_catch_stop_iteration(self):
118118
[((1, '\x00-2\x01'), (1, '\x00+3\x01'), True)],
119119
)
120120

121+
def test_mdiff_lopsided_replace(self):
122+
self.assertEqual(
123+
list(difflib._mdiff(["a\n"] * 4, ["b\n"])),
124+
[
125+
((1, '\x00-a\n\x01'), (1, '\x00+b\n\x01'), True),
126+
((2, '\x00-a\n\x01'), ('', '\n'), True),
127+
((3, '\x00-a\n\x01'), ('', '\n'), True),
128+
((4, '\x00-a\n\x01'), ('', '\n'), True),
129+
],
130+
)
131+
self.assertEqual(
132+
list(difflib._mdiff(["a\n"], ["b\n"] * 4)),
133+
[
134+
((1, '\x00-a\n\x01'), (1, '\x00+b\n\x01'), True),
135+
(('', '\n'), (2, '\x00+b\n\x01'), True),
136+
(('', '\n'), (3, '\x00+b\n\x01'), True),
137+
(('', '\n'), (4, '\x00+b\n\x01'), True),
138+
],
139+
)
140+
121141

122142
patch914575_from1 = """
123143
1. Beautiful is beTTer than ugly.

0 commit comments

Comments
 (0)