annotate Lib/difflib.py @ 57685:2fdcd73c32aa

Merged revisions 76785 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76785 | benjamin.peterson | 2009-12-13 08:18:08 -0600 (Sun, 13 Dec 2009) | 1 line add 2.6.x point releases ........
author Benjamin Peterson <benjamin@python.org>
date Sun, 13 Dec 2009 14:21:46 +0000
parents 3a2b149ae66e
children bf94b6a73fc8 fcfe324663a6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1 #! /usr/bin/env python
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
3 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
4 Module difflib -- helpers for computing deltas between objects.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
5
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
6 Function get_close_matches(word, possibilities, n=3, cutoff=0.6):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
7 Use SequenceMatcher to return list of the best "good enough" matches.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
8
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
9 Function context_diff(a, b):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
10 For two lists of strings, return a delta in context diff format.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
11
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
12 Function ndiff(a, b):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
13 Return a delta: the difference between `a` and `b` (lists of strings).
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
14
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
15 Function restore(delta, which):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
16 Return one of the two sequences that generated an ndiff delta.
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
17
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
18 Function unified_diff(a, b):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
19 For two lists of strings, return a delta in unified diff format.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
20
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
21 Class SequenceMatcher:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
22 A flexible class for comparing pairs of sequences of any type.
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
23
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
24 Class Differ:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
25 For producing human-readable deltas from sequences of lines of text.
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
26
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
27 Class HtmlDiff:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
28 For producing HTML side by side comparison with change highlights.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
29 """
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
30
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
31 __all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher',
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
32 'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff',
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
33 'unified_diff', 'HtmlDiff', 'Match']
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
34
32339
408a40e65247 Apply heapq.nlargest() to find best matches.
Raymond Hettinger <python@rcn.com>
parents: 31515
diff changeset
35 import heapq
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
36 from collections import namedtuple as _namedtuple
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
37
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
38 Match = _namedtuple('Match', 'a b size')
32339
408a40e65247 Apply heapq.nlargest() to find best matches.
Raymond Hettinger <python@rcn.com>
parents: 31515
diff changeset
39
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
40 def _calculate_ratio(matches, length):
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
41 if length:
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
42 return 2.0 * matches / length
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
43 return 1.0
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
44
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
45 class SequenceMatcher:
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
46
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
47 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
48 SequenceMatcher is a flexible class for comparing pairs of sequences of
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
49 any type, so long as the sequence elements are hashable. The basic
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
50 algorithm predates, and is a little fancier than, an algorithm
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
51 published in the late 1980's by Ratcliff and Obershelp under the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
52 hyperbolic name "gestalt pattern matching". The basic idea is to find
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
53 the longest contiguous matching subsequence that contains no "junk"
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
54 elements (R-O doesn't address junk). The same idea is then applied
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
55 recursively to the pieces of the sequences to the left and to the right
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
56 of the matching subsequence. This does not yield minimal edit
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
57 sequences, but does tend to yield matches that "look right" to people.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
58
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
59 SequenceMatcher tries to compute a "human-friendly diff" between two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
60 sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
61 longest *contiguous* & junk-free matching subsequence. That's what
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
62 catches peoples' eyes. The Windows(tm) windiff has another interesting
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
63 notion, pairing up elements that appear uniquely in each sequence.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
64 That, and the method here, appear to yield more intuitive difference
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
65 reports than does diff. This method appears to be the least vulnerable
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
66 to synching up on blocks of "junk lines", though (like blank lines in
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
67 ordinary text files, or maybe "<P>" lines in HTML files). That may be
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
68 because this is the only method of the 3 that has a *concept* of
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
69 "junk" <wink>.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
70
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
71 Example, comparing two strings, and considering blanks to be "junk":
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
72
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
73 >>> s = SequenceMatcher(lambda x: x == " ",
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
74 ... "private Thread currentThread;",
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
75 ... "private volatile Thread currentThread;")
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
76 >>>
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
77
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
78 .ratio() returns a float in [0, 1], measuring the "similarity" of the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
79 sequences. As a rule of thumb, a .ratio() value over 0.6 means the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
80 sequences are close matches:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
81
40786
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
82 >>> print(round(s.ratio(), 3))
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
83 0.866
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
84 >>>
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
85
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
86 If you're only interested in where the sequences match,
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
87 .get_matching_blocks() is handy:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
88
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
89 >>> for block in s.get_matching_blocks():
40786
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
90 ... print("a[%d] and b[%d] match for %d elements" % block)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
91 a[0] and b[0] match for 8 elements
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
92 a[8] and b[17] match for 21 elements
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
93 a[29] and b[38] match for 0 elements
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
94
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
95 Note that the last tuple returned by .get_matching_blocks() is always a
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
96 dummy, (len(a), len(b), 0), and this is the only case in which the last
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
97 tuple element (number of elements matched) is 0.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
98
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
99 If you want to know how to change the first sequence into the second,
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
100 use .get_opcodes():
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
101
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
102 >>> for opcode in s.get_opcodes():
40786
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
103 ... print("%6s a[%d:%d] b[%d:%d]" % opcode)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
104 equal a[0:8] b[0:8]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
105 insert a[8:8] b[8:17]
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
106 equal a[8:29] b[17:38]
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
107
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
108 See the Differ class for a fancy human-friendly file differencer, which
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
109 uses SequenceMatcher both to compare sequences of lines, and to compare
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
110 sequences of characters within similar (near-matching) lines.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
111
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
112 See also function get_close_matches() in this module, which shows how
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
113 simple code building on SequenceMatcher can be used to do useful work.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
114
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
115 Timing: Basic R-O is cubic time worst case and quadratic time expected
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
116 case. SequenceMatcher is quadratic time for the worst case and has
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
117 expected-case behavior dependent in a complicated way on how many
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
118 elements the sequences have in common; best case time is linear.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
119
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
120 Methods:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
121
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
122 __init__(isjunk=None, a='', b='')
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
123 Construct a SequenceMatcher.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
124
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
125 set_seqs(a, b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
126 Set the two sequences to be compared.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
127
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
128 set_seq1(a)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
129 Set the first sequence to be compared.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
130
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
131 set_seq2(b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
132 Set the second sequence to be compared.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
133
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
134 find_longest_match(alo, ahi, blo, bhi)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
135 Find longest matching block in a[alo:ahi] and b[blo:bhi].
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
136
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
137 get_matching_blocks()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
138 Return list of triples describing matching subsequences.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
139
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
140 get_opcodes()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
141 Return list of 5-tuples describing how to turn a into b.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
142
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
143 ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
144 Return a measure of the sequences' similarity (float in [0,1]).
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
145
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
146 quick_ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
147 Return an upper bound on .ratio() relatively quickly.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
148
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
149 real_quick_ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
150 Return an upper bound on ratio() very quickly.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
151 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
152
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
153 def __init__(self, isjunk=None, a='', b=''):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
154 """Construct a SequenceMatcher.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
155
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
156 Optional arg isjunk is None (the default), or a one-argument
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
157 function that takes a sequence element and returns true iff the
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
158 element is junk. None is equivalent to passing "lambda x: 0", i.e.
16695
e14c5f34fa05 Fix a few small typos in the docstrings.
Fred Drake <fdrake@acm.org>
parents: 16551
diff changeset
159 no elements are considered to be junk. For example, pass
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
160 lambda x: x in " \\t"
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
161 if you're comparing lines as sequences of characters, and don't
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
162 want to synch up on blanks or hard tabs.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
163
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
164 Optional arg a is the first of two sequences to be compared. By
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
165 default, an empty string. The elements of a must be hashable. See
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
166 also .set_seqs() and .set_seq1().
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
167
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
168 Optional arg b is the second of two sequences to be compared. By
16695
e14c5f34fa05 Fix a few small typos in the docstrings.
Fred Drake <fdrake@acm.org>
parents: 16551
diff changeset
169 default, an empty string. The elements of b must be hashable. See
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
170 also .set_seqs() and .set_seq2().
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
171 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
172
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
173 # Members:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
174 # a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
175 # first sequence
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
176 # b
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
177 # second sequence; differences are computed as "what do
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
178 # we need to do to 'a' to change it into 'b'?"
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
179 # b2j
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
180 # for x in b, b2j[x] is a list of the indices (into b)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
181 # at which x appears; junk elements do not appear
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
182 # fullbcount
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
183 # for x in b, fullbcount[x] == the number of times x
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
184 # appears in b; only materialized if really needed (used
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
185 # only for computing quick_ratio())
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
186 # matching_blocks
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
187 # a list of (i, j, k) triples, where a[i:i+k] == b[j:j+k];
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
188 # ascending & non-overlapping in i and in j; terminated by
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
189 # a dummy (len(a), len(b), 0) sentinel
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
190 # opcodes
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
191 # a list of (tag, i1, i2, j1, j2) tuples, where tag is
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
192 # one of
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
193 # 'replace' a[i1:i2] should be replaced by b[j1:j2]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
194 # 'delete' a[i1:i2] should be deleted
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
195 # 'insert' b[j1:j2] should be inserted
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
196 # 'equal' a[i1:i2] == b[j1:j2]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
197 # isjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
198 # a user-supplied function taking a sequence element and
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
199 # returning true iff the element is "junk" -- this has
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
200 # subtle but helpful effects on the algorithm, which I'll
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
201 # get around to writing up someday <0.9 wink>.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
202 # DON'T USE! Only __chain_b uses this. Use isbjunk.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
203 # isbjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
204 # for x in b, isbjunk(x) == isjunk(x) but much faster;
39575
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
205 # it's really the __contains__ method of a hidden dict.
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
206 # DOES NOT WORK for x in a!
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
207 # isbpopular
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
208 # for x in b, isbpopular(x) is true iff b is reasonably long
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
209 # (at least 200 elements) and x accounts for more than 1% of
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
210 # its elements. DOES NOT WORK for x in a!
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
211
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
212 self.isjunk = isjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
213 self.a = self.b = None
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
214 self.set_seqs(a, b)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
215
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
216 def set_seqs(self, a, b):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
217 """Set the two sequences to be compared.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
218
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
219 >>> s = SequenceMatcher()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
220 >>> s.set_seqs("abcd", "bcde")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
221 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
222 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
223 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
224
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
225 self.set_seq1(a)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
226 self.set_seq2(b)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
227
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
228 def set_seq1(self, a):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
229 """Set the first sequence to be compared.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
230
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
231 The second sequence to be compared is not changed.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
232
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
233 >>> s = SequenceMatcher(None, "abcd", "bcde")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
234 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
235 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
236 >>> s.set_seq1("bcde")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
237 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
238 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
239 >>>
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
240
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
241 SequenceMatcher computes and caches detailed information about the
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
242 second sequence, so if you want to compare one sequence S against
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
243 many sequences, use .set_seq2(S) once and call .set_seq1(x)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
244 repeatedly for each of the other sequences.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
245
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
246 See also set_seqs() and set_seq2().
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
247 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
248
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
249 if a is self.a:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
250 return
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
251 self.a = a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
252 self.matching_blocks = self.opcodes = None
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
253
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
254 def set_seq2(self, b):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
255 """Set the second sequence to be compared.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
256
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
257 The first sequence to be compared is not changed.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
258
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
259 >>> s = SequenceMatcher(None, "abcd", "bcde")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
260 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
261 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
262 >>> s.set_seq2("abcd")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
263 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
264 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
265 >>>
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
266
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
267 SequenceMatcher computes and caches detailed information about the
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
268 second sequence, so if you want to compare one sequence S against
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
269 many sequences, use .set_seq2(S) once and call .set_seq1(x)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
270 repeatedly for each of the other sequences.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
271
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
272 See also set_seqs() and set_seq1().
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
273 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
274
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
275 if b is self.b:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
276 return
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
277 self.b = b
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
278 self.matching_blocks = self.opcodes = None
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
279 self.fullbcount = None
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
280 self.__chain_b()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
281
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
282 # For each element x in b, set b2j[x] to a list of the indices in
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
283 # b where x appears; the indices are in increasing order; note that
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
284 # the number of times x appears in b is len(b2j[x]) ...
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
285 # when self.isjunk is defined, junk elements don't show up in this
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
286 # map at all, which stops the central find_longest_match method
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
287 # from starting any matching block at a junk element ...
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
288 # also creates the fast isbjunk function ...
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
289 # b2j also does not contain entries for "popular" elements, meaning
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
290 # elements that account for more than 1% of the total elements, and
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
291 # when the sequence is reasonably large (>= 200 elements); this can
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
292 # be viewed as an adaptive notion of semi-junk, and yields an enormous
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
293 # speedup when, e.g., comparing program files with hundreds of
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
294 # instances of "return NULL;" ...
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
295 # note that this is only called when b changes; so for cross-product
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
296 # kinds of matches, it's best to call set_seq2 once, then set_seq1
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
297 # repeatedly
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
298
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
299 def __chain_b(self):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
300 # Because isjunk is a user-defined (not C) function, and we test
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
301 # for junk a LOT, it's important to minimize the number of calls.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
302 # Before the tricks described here, __chain_b was by far the most
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
303 # time-consuming routine in the whole module! If anyone sees
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
304 # Jim Roskind, thank him again for profile.py -- I never would
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
305 # have guessed that.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
306 # The first trick is to build b2j ignoring the possibility
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
307 # of junk. I.e., we don't call isjunk at all yet. Throwing
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
308 # out the junk later is much cheaper than building b2j "right"
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
309 # from the start.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
310 b = self.b
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
311 n = len(b)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
312 self.b2j = b2j = {}
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
313 populardict = {}
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
314 for i, elt in enumerate(b):
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
315 if elt in b2j:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
316 indices = b2j[elt]
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
317 if n >= 200 and len(indices) * 100 > n:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
318 populardict[elt] = 1
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
319 del indices[:]
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
320 else:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
321 indices.append(i)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
322 else:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
323 b2j[elt] = [i]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
324
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
325 # Purge leftover indices for popular elements.
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
326 for elt in populardict:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
327 del b2j[elt]
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
328
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
329 # Now b2j.keys() contains elements uniquely, and especially when
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
330 # the sequence is a string, that's usually a good deal smaller
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
331 # than len(string). The difference is the number of isjunk calls
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
332 # saved.
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
333 isjunk = self.isjunk
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
334 junkdict = {}
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
335 if isjunk:
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
336 for d in populardict, b2j:
40809
f340cb045bf9 - PEP 3106: dict.iterkeys(), .iteritems(), .itervalues() are now gone;
Guido van Rossum <guido@python.org>
parents: 40786
diff changeset
337 for elt in list(d.keys()):
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
338 if isjunk(elt):
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
339 junkdict[elt] = 1
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
340 del d[elt]
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
341
23620
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 23300
diff changeset
342 # Now for x in b, isjunk(x) == x in junkdict, but the
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
343 # latter is much faster. Note too that while there may be a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
344 # lot of junk in the sequence, the number of *unique* junk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
345 # elements is probably small. So the memory burden of keeping
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
346 # this dict alive is likely trivial compared to the size of b2j.
39575
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
347 self.isbjunk = junkdict.__contains__
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
348 self.isbpopular = populardict.__contains__
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
349
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
350 def find_longest_match(self, alo, ahi, blo, bhi):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
351 """Find longest matching block in a[alo:ahi] and b[blo:bhi].
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
352
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
353 If isjunk is not defined:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
354
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
355 Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
356 alo <= i <= i+k <= ahi
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
357 blo <= j <= j+k <= bhi
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
358 and for all (i',j',k') meeting those conditions,
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
359 k >= k'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
360 i <= i'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
361 and if i == i', j <= j'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
362
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
363 In other words, of all maximal matching blocks, return one that
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
364 starts earliest in a, and of all those maximal matching blocks that
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
365 start earliest in a, return the one that starts earliest in b.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
366
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
367 >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
368 >>> s.find_longest_match(0, 5, 0, 9)
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
369 Match(a=0, b=4, size=5)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
370
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
371 If isjunk is defined, first the longest matching block is
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
372 determined as above, but with the additional restriction that no
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
373 junk element appears in the block. Then that block is extended as
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
374 far as possible by matching (only) junk elements on both sides. So
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
375 the resulting block never matches on junk except as identical junk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
376 happens to be adjacent to an "interesting" match.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
377
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
378 Here's the same example as before, but considering blanks to be
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
379 junk. That prevents " abcd" from matching the " abcd" at the tail
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
380 end of the second sequence directly. Instead only the "abcd" can
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
381 match, and matches the leftmost "abcd" in the second sequence:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
382
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
383 >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
384 >>> s.find_longest_match(0, 5, 0, 9)
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
385 Match(a=1, b=0, size=4)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
386
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
387 If no blocks match, return (alo, blo, 0).
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
388
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
389 >>> s = SequenceMatcher(None, "ab", "c")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
390 >>> s.find_longest_match(0, 2, 0, 1)
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
391 Match(a=0, b=0, size=0)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
392 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
393
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
394 # CAUTION: stripping common prefix or suffix would be incorrect.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
395 # E.g.,
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
396 # ab
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
397 # acab
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
398 # Longest matching block is "ab", but if common prefix is
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
399 # stripped, it's "a" (tied with "b"). UNIX(tm) diff does so
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
400 # strip, so ends up claiming that ab is changed to acab by
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
401 # inserting "ca" in the middle. That's minimal but unintuitive:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
402 # "it's obvious" that someone inserted "ac" at the front.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
403 # Windiff ends up at the same place as diff, but by pairing up
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
404 # the unique 'b's and then matching the first two 'a's.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
405
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
406 a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.isbjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
407 besti, bestj, bestsize = alo, blo, 0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
408 # find longest junk-free match
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
409 # during an iteration of the loop, j2len[j] = length of longest
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
410 # junk-free match ending with a[i-1] and b[j]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
411 j2len = {}
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
412 nothing = []
41642
a6eb6acfe04a Merged revisions 55007-55179 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41554
diff changeset
413 for i in range(alo, ahi):
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
414 # look at all instances of a[i] in b; note that because
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
415 # b2j has no junk keys, the loop is skipped if a[i] is junk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
416 j2lenget = j2len.get
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
417 newj2len = {}
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
418 for j in b2j.get(a[i], nothing):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
419 # a[i] matches b[j]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
420 if j < blo:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
421 continue
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
422 if j >= bhi:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
423 break
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
424 k = newj2len[j] = j2lenget(j-1, 0) + 1
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
425 if k > bestsize:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
426 besti, bestj, bestsize = i-k+1, j-k+1, k
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
427 j2len = newj2len
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
428
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
429 # Extend the best by non-junk elements on each end. In particular,
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
430 # "popular" non-junk elements aren't in b2j, which greatly speeds
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
431 # the inner loop above, but also means "the best" match so far
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
432 # doesn't contain any junk *or* popular non-junk elements.
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
433 while besti > alo and bestj > blo and \
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
434 not isbjunk(b[bestj-1]) and \
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
435 a[besti-1] == b[bestj-1]:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
436 besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
437 while besti+bestsize < ahi and bestj+bestsize < bhi and \
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
438 not isbjunk(b[bestj+bestsize]) and \
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
439 a[besti+bestsize] == b[bestj+bestsize]:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
440 bestsize += 1
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
441
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
442 # Now that we have a wholly interesting match (albeit possibly
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
443 # empty!), we may as well suck up the matching junk on each
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
444 # side of it too. Can't think of a good reason not to, and it
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
445 # saves post-processing the (possibly considerable) expense of
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
446 # figuring out what to do with it. In the case of an empty
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
447 # interesting match, this is clearly the right thing to do,
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
448 # because no other kind of match is possible in the regions.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
449 while besti > alo and bestj > blo and \
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
450 isbjunk(b[bestj-1]) and \
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
451 a[besti-1] == b[bestj-1]:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
452 besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
453 while besti+bestsize < ahi and bestj+bestsize < bhi and \
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
454 isbjunk(b[bestj+bestsize]) and \
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
455 a[besti+bestsize] == b[bestj+bestsize]:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
456 bestsize = bestsize + 1
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
457
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
458 return Match(besti, bestj, bestsize)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
459
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
460 def get_matching_blocks(self):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
461 """Return list of triples describing matching subsequences.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
462
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
463 Each triple is of the form (i, j, n), and means that
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
464 a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
465 i and in j. New in Python 2.5, it's also guaranteed that if
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
466 (i, j, n) and (i', j', n') are adjacent triples in the list, and
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
467 the second is not the last triple in the list, then i+n != i' or
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
468 j+n != j'. IOW, adjacent triples never describe adjacent equal
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
469 blocks.
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
470
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
471 The last triple is a dummy, (len(a), len(b), 0), and is the only
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
472 triple with n==0.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
473
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
474 >>> s = SequenceMatcher(None, "abxcd", "abcd")
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
475 >>> list(s.get_matching_blocks())
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
476 [Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)]
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
477 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
478
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
479 if self.matching_blocks is not None:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
480 return self.matching_blocks
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
481 la, lb = len(self.a), len(self.b)
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
482
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
483 # This is most naturally expressed as a recursive algorithm, but
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
484 # at least one user bumped into extreme use cases that exceeded
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
485 # the recursion limit on their box. So, now we maintain a list
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
486 # ('queue`) of blocks we still need to look at, and append partial
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
487 # results to `matching_blocks` in a loop; the matches are sorted
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
488 # at the end.
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
489 queue = [(0, la, 0, lb)]
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
490 matching_blocks = []
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
491 while queue:
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
492 alo, ahi, blo, bhi = queue.pop()
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
493 i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi)
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
494 # a[alo:i] vs b[blo:j] unknown
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
495 # a[i:i+k] same as b[j:j+k]
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
496 # a[i+k:ahi] vs b[j+k:bhi] unknown
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
497 if k: # if k is 0, there was no matching block
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
498 matching_blocks.append(x)
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
499 if alo < i and blo < j:
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
500 queue.append((alo, i, blo, j))
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
501 if i+k < ahi and j+k < bhi:
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
502 queue.append((i+k, ahi, j+k, bhi))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
503 matching_blocks.sort()
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
504
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
505 # It's possible that we have adjacent equal blocks in the
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
506 # matching_blocks list now. Starting with 2.5, this code was added
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
507 # to collapse them.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
508 i1 = j1 = k1 = 0
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
509 non_adjacent = []
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
510 for i2, j2, k2 in matching_blocks:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
511 # Is this block adjacent to i1, j1, k1?
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
512 if i1 + k1 == i2 and j1 + k1 == j2:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
513 # Yes, so collapse them -- this just increases the length of
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
514 # the first block by the length of the second, and the first
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
515 # block so lengthened remains the block to compare against.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
516 k1 += k2
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
517 else:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
518 # Not adjacent. Remember the first block (k1==0 means it's
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
519 # the dummy we started with), and make the second block the
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
520 # new block to compare against.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
521 if k1:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
522 non_adjacent.append((i1, j1, k1))
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
523 i1, j1, k1 = i2, j2, k2
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
524 if k1:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
525 non_adjacent.append((i1, j1, k1))
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
526
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
527 non_adjacent.append( (la, lb, 0) )
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
528 self.matching_blocks = non_adjacent
44643
d8e4342c145e Merged revisions 59883-59920 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
529 return map(Match._make, self.matching_blocks)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
530
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
531 def get_opcodes(self):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
532 """Return list of 5-tuples describing how to turn a into b.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
533
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
534 Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
535 has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
536 tuple preceding it, and likewise for j1 == the previous j2.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
537
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
538 The tags are strings, with these meanings:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
539
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
540 'replace': a[i1:i2] should be replaced by b[j1:j2]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
541 'delete': a[i1:i2] should be deleted.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
542 Note that j1==j2 in this case.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
543 'insert': b[j1:j2] should be inserted at a[i1:i1].
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
544 Note that i1==i2 in this case.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
545 'equal': a[i1:i2] == b[j1:j2]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
546
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
547 >>> a = "qabxcd"
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
548 >>> b = "abycdf"
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
549 >>> s = SequenceMatcher(None, a, b)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
550 >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
40786
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
551 ... print(("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
552 ... (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2])))
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
553 delete a[0:1] (q) b[0:0] ()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
554 equal a[1:3] (ab) b[0:2] (ab)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
555 replace a[3:4] (x) b[2:3] (y)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
556 equal a[4:6] (cd) b[3:5] (cd)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
557 insert a[6:6] () b[5:6] (f)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
558 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
559
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
560 if self.opcodes is not None:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
561 return self.opcodes
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
562 i = j = 0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
563 self.opcodes = answer = []
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
564 for ai, bj, size in self.get_matching_blocks():
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
565 # invariant: we've pumped out correct diffs to change
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
566 # a[:i] into b[:j], and the next matching block is
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
567 # a[ai:ai+size] == b[bj:bj+size]. So we need to pump
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
568 # out a diff to change a[i:ai] into b[j:bj], pump out
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
569 # the matching block, and move (i,j) beyond the match
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
570 tag = ''
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
571 if i < ai and j < bj:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
572 tag = 'replace'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
573 elif i < ai:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
574 tag = 'delete'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
575 elif j < bj:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
576 tag = 'insert'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
577 if tag:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
578 answer.append( (tag, i, ai, j, bj) )
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
579 i, j = ai+size, bj+size
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
580 # the list of matching blocks is terminated by a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
581 # sentinel with size 0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
582 if size:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
583 answer.append( ('equal', ai, i, bj, j) )
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
584 return answer
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
585
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
586 def get_grouped_opcodes(self, n=3):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
587 """ Isolate change clusters by eliminating ranges with no changes.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
588
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
589 Return a generator of groups with upto n lines of context.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
590 Each group is in the same format as returned by get_opcodes().
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
591
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
592 >>> from pprint import pprint
42142
a53e48be6df9 Merged revisions 56125-56153 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42132
diff changeset
593 >>> a = list(map(str, range(1,40)))
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
594 >>> b = a[:]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
595 >>> b[8:8] = ['i'] # Make an insertion
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
596 >>> b[20] += 'x' # Make a replacement
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
597 >>> b[23:28] = [] # Make a deletion
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
598 >>> b[30] += 'y' # Make another replacement
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
599 >>> pprint(list(SequenceMatcher(None,a,b).get_grouped_opcodes()))
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
600 [[('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)],
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
601 [('equal', 16, 19, 17, 20),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
602 ('replace', 19, 20, 20, 21),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
603 ('equal', 20, 22, 21, 23),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
604 ('delete', 22, 27, 23, 23),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
605 ('equal', 27, 30, 23, 26)],
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
606 [('equal', 31, 34, 27, 30),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
607 ('replace', 34, 35, 30, 31),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
608 ('equal', 35, 38, 31, 34)]]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
609 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
610
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
611 codes = self.get_opcodes()
32612
5546c7ae24f7 SequenceMatcher(None, [], []).get_grouped_opcodes() now returns a generator
Brett Cannon <bcannon@gmail.com>
parents: 32357
diff changeset
612 if not codes:
5546c7ae24f7 SequenceMatcher(None, [], []).get_grouped_opcodes() now returns a generator
Brett Cannon <bcannon@gmail.com>
parents: 32357
diff changeset
613 codes = [("equal", 0, 1, 0, 1)]
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
614 # Fixup leading and trailing groups if they show no changes.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
615 if codes[0][0] == 'equal':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
616 tag, i1, i2, j1, j2 = codes[0]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
617 codes[0] = tag, max(i1, i2-n), i2, max(j1, j2-n), j2
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
618 if codes[-1][0] == 'equal':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
619 tag, i1, i2, j1, j2 = codes[-1]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
620 codes[-1] = tag, i1, min(i2, i1+n), j1, min(j2, j1+n)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
621
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
622 nn = n + n
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
623 group = []
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
624 for tag, i1, i2, j1, j2 in codes:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
625 # End the current group and start a new one whenever
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
626 # there is a large range with no changes.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
627 if tag == 'equal' and i2-i1 > nn:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
628 group.append((tag, i1, min(i2, i1+n), j1, min(j2, j1+n)))
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
629 yield group
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
630 group = []
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
631 i1, j1 = max(i1, i2-n), max(j1, j2-n)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
632 group.append((tag, i1, i2, j1 ,j2))
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
633 if group and not (len(group)==1 and group[0][0] == 'equal'):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
634 yield group
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
635
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
636 def ratio(self):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
637 """Return a measure of the sequences' similarity (float in [0,1]).
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
638
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
639 Where T is the total number of elements in both sequences, and
32867
8d25835f88ae Repair typo in docstring.
Tim Peters <tim.peters@gmail.com>
parents: 32612
diff changeset
640 M is the number of matches, this is 2.0*M / T.
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
641 Note that this is 1 if the sequences are identical, and 0 if
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
642 they have nothing in common.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
643
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
644 .ratio() is expensive to compute if you haven't already computed
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
645 .get_matching_blocks() or .get_opcodes(), in which case you may
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
646 want to try .quick_ratio() or .real_quick_ratio() first to get an
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
647 upper bound.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
648
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
649 >>> s = SequenceMatcher(None, "abcd", "bcde")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
650 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
651 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
652 >>> s.quick_ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
653 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
654 >>> s.real_quick_ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
655 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
656 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
657
39627
e86c0b29b4a2 Kill reduce(). A coproduction of John Reese, Jacques Frechet, and Alex M.
Guido van Rossum <guido@python.org>
parents: 39575
diff changeset
658 matches = sum(triple[-1] for triple in self.get_matching_blocks())
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
659 return _calculate_ratio(matches, len(self.a) + len(self.b))
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
660
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
661 def quick_ratio(self):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
662 """Return an upper bound on ratio() relatively quickly.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
663
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
664 This isn't defined beyond that it is an upper bound on .ratio(), and
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
665 is faster to compute.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
666 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
667
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
668 # viewing a and b as multisets, set matches to the cardinality
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
669 # of their intersection; this counts the number of matches
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
670 # without regard to order, so is clearly an upper bound
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
671 if self.fullbcount is None:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
672 self.fullbcount = fullbcount = {}
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
673 for elt in self.b:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
674 fullbcount[elt] = fullbcount.get(elt, 0) + 1
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
675 fullbcount = self.fullbcount
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
676 # avail[x] is the number of times x appears in 'b' less the
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
677 # number of times we've seen it in 'a' so far ... kinda
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
678 avail = {}
39575
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
679 availhas, matches = avail.__contains__, 0
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
680 for elt in self.a:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
681 if availhas(elt):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
682 numb = avail[elt]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
683 else:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
684 numb = fullbcount.get(elt, 0)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
685 avail[elt] = numb - 1
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
686 if numb > 0:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
687 matches = matches + 1
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
688 return _calculate_ratio(matches, len(self.a) + len(self.b))
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
689
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
690 def real_quick_ratio(self):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
691 """Return an upper bound on ratio() very quickly.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
692
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
693 This isn't defined beyond that it is an upper bound on .ratio(), and
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
694 is faster to compute than either .ratio() or .quick_ratio().
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
695 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
696
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
697 la, lb = len(self.a), len(self.b)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
698 # can't have more matches than the number of elements in the
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
699 # shorter sequence
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
700 return _calculate_ratio(min(la, lb), la + lb)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
701
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
702 def get_close_matches(word, possibilities, n=3, cutoff=0.6):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
703 """Use SequenceMatcher to return list of the best "good enough" matches.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
704
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
705 word is a sequence for which close matches are desired (typically a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
706 string).
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
707
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
708 possibilities is a list of sequences against which to match word
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
709 (typically a list of strings).
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
710
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
711 Optional arg n (default 3) is the maximum number of close matches to
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
712 return. n must be > 0.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
713
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
714 Optional arg cutoff (default 0.6) is a float in [0, 1]. Possibilities
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
715 that don't score at least that similar to word are ignored.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
716
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
717 The best (no more than n) matches among the possibilities are returned
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
718 in a list, sorted by similarity score, most similar first.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
719
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
720 >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"])
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
721 ['apple', 'ape']
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
722 >>> import keyword as _keyword
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
723 >>> get_close_matches("wheel", _keyword.kwlist)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
724 ['while']
42132
863ed7cd45dc Merged revisions 56020-56124 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41642
diff changeset
725 >>> get_close_matches("Apple", _keyword.kwlist)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
726 []
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
727 >>> get_close_matches("accept", _keyword.kwlist)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
728 ['except']
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
729 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
730
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
731 if not n > 0:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
diff changeset
732 raise ValueError("n must be > 0: %r" % (n,))
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
733 if not 0.0 <= cutoff <= 1.0:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
diff changeset
734 raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,))
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
735 result = []
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
736 s = SequenceMatcher()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
737 s.set_seq2(word)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
738 for x in possibilities:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
739 s.set_seq1(x)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
740 if s.real_quick_ratio() >= cutoff and \
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
741 s.quick_ratio() >= cutoff and \
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
742 s.ratio() >= cutoff:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
743 result.append((s.ratio(), x))
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
744
30698
3e3fd56ce595 Let library modules use the new keyword arguments for list.sort().
Raymond Hettinger <python@rcn.com>
parents: 29891
diff changeset
745 # Move the best scorers to head of list
32357
a46bde9e0c74 Reverse argument order for nsmallest() and nlargest().
Raymond Hettinger <python@rcn.com>
parents: 32339
diff changeset
746 result = heapq.nlargest(n, result)
30698
3e3fd56ce595 Let library modules use the new keyword arguments for list.sort().
Raymond Hettinger <python@rcn.com>
parents: 29891
diff changeset
747 # Strip scores for the best n matches
32339
408a40e65247 Apply heapq.nlargest() to find best matches.
Raymond Hettinger <python@rcn.com>
parents: 31515
diff changeset
748 return [x for score, x in result]
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
749
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
750 def _count_leading(line, ch):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
751 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
752 Return number of `ch` characters at the start of `line`.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
753
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
754 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
755
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
756 >>> _count_leading(' abc', ' ')
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
757 3
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
758 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
759
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
760 i, n = 0, len(line)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
761 while i < n and line[i] == ch:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
762 i += 1
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
763 return i
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
764
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
765 class Differ:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
766 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
767 Differ is a class for comparing sequences of lines of text, and
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
768 producing human-readable differences or deltas. Differ uses
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
769 SequenceMatcher both to compare sequences of lines, and to compare
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
770 sequences of characters within similar (near-matching) lines.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
771
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
772 Each line of a Differ delta begins with a two-letter code:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
773
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
774 '- ' line unique to sequence 1
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
775 '+ ' line unique to sequence 2
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
776 ' ' line common to both sequences
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
777 '? ' line not present in either input sequence
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
778
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
779 Lines beginning with '? ' attempt to guide the eye to intraline
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
780 differences, and were not present in either input sequence. These lines
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
781 can be confusing if the sequences contain tab characters.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
782
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
783 Note that Differ makes no claim to produce a *minimal* diff. To the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
784 contrary, minimal diffs are often counter-intuitive, because they synch
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
785 up anywhere possible, sometimes accidental matches 100 pages apart.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
786 Restricting synch points to contiguous matches preserves some notion of
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
787 locality, at the occasional cost of producing a longer diff.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
788
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
789 Example: Comparing two texts.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
790
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
791 First we set up the texts, sequences of individual single-line strings
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
792 ending with newlines (such sequences can also be obtained from the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
793 `readlines()` method of file-like objects):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
794
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
795 >>> text1 = ''' 1. Beautiful is better than ugly.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
796 ... 2. Explicit is better than implicit.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
797 ... 3. Simple is better than complex.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
798 ... 4. Complex is better than complicated.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
799 ... '''.splitlines(1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
800 >>> len(text1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
801 4
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
802 >>> text1[0][-1]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
803 '\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
804 >>> text2 = ''' 1. Beautiful is better than ugly.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
805 ... 3. Simple is better than complex.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
806 ... 4. Complicated is better than complex.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
807 ... 5. Flat is better than nested.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
808 ... '''.splitlines(1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
809
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
810 Next we instantiate a Differ object:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
811
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
812 >>> d = Differ()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
813
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
814 Note that when instantiating a Differ object we may pass functions to
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
815 filter out line and character 'junk'. See Differ.__init__ for details.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
816
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
817 Finally, we compare the two:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
818
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
819 >>> result = list(d.compare(text1, text2))
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
820
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
821 'result' is a list of strings, so let's pretty-print it:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
822
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
823 >>> from pprint import pprint as _pprint
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
824 >>> _pprint(result)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
825 [' 1. Beautiful is better than ugly.\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
826 '- 2. Explicit is better than implicit.\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
827 '- 3. Simple is better than complex.\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
828 '+ 3. Simple is better than complex.\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
829 '? ++\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
830 '- 4. Complex is better than complicated.\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
831 '? ^ ---- ^\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
832 '+ 4. Complicated is better than complex.\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
833 '? ++++ ^ ^\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
834 '+ 5. Flat is better than nested.\n']
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
835
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
836 As a single multi-line string it looks like this:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
837
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
838 >>> print(''.join(result), end="")
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
839 1. Beautiful is better than ugly.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
840 - 2. Explicit is better than implicit.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
841 - 3. Simple is better than complex.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
842 + 3. Simple is better than complex.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
843 ? ++
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
844 - 4. Complex is better than complicated.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
845 ? ^ ---- ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
846 + 4. Complicated is better than complex.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
847 ? ++++ ^ ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
848 + 5. Flat is better than nested.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
849
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
850 Methods:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
851
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
852 __init__(linejunk=None, charjunk=None)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
853 Construct a text differencer, with optional filters.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
854
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
855 compare(a, b)
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
856 Compare two sequences of lines; generate the resulting delta.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
857 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
858
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
859 def __init__(self, linejunk=None, charjunk=None):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
860 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
861 Construct a text differencer, with optional filters.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
862
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
863 The two optional keyword parameters are for filter functions:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
864
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
865 - `linejunk`: A function that should accept a single string argument,
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
866 and return true iff the string is junk. The module-level function
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
867 `IS_LINE_JUNK` may be used to filter out lines without visible
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
868 characters, except for at most one splat ('#'). It is recommended
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
869 to leave linejunk None; as of Python 2.3, the underlying
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
870 SequenceMatcher class has grown an adaptive notion of "noise" lines
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
871 that's better than any static definition the author has ever been
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
872 able to craft.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
873
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
874 - `charjunk`: A function that should accept a string of length 1. The
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
875 module-level function `IS_CHARACTER_JUNK` may be used to filter out
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
876 whitespace characters (a blank or tab; **note**: bad idea to include
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
877 newline in this!). Use of IS_CHARACTER_JUNK is recommended.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
878 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
879
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
880 self.linejunk = linejunk
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
881 self.charjunk = charjunk
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
882
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
883 def compare(self, a, b):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
884 r"""
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
885 Compare two sequences of lines; generate the resulting delta.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
886
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
887 Each sequence must contain individual single-line strings ending with
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
888 newlines. Such sequences can be obtained from the `readlines()` method
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
889 of file-like objects. The delta generated also consists of newline-
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
890 terminated strings, ready to be printed as-is via the writeline()
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
891 method of a file-like object.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
892
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
893 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
894
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
895 >>> print(''.join(Differ().compare('one\ntwo\nthree\n'.splitlines(1),
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
896 ... 'ore\ntree\nemu\n'.splitlines(1))),
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
897 ... end="")
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
898 - one
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
899 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
900 + ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
901 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
902 - two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
903 - three
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
904 ? -
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
905 + tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
906 + emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
907 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
908
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
909 cruncher = SequenceMatcher(self.linejunk, a, b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
910 for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
911 if tag == 'replace':
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
912 g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
913 elif tag == 'delete':
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
914 g = self._dump('-', a, alo, ahi)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
915 elif tag == 'insert':
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
916 g = self._dump('+', b, blo, bhi)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
917 elif tag == 'equal':
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
918 g = self._dump(' ', a, alo, ahi)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
919 else:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 42142
diff changeset
920 raise ValueError('unknown tag %r' % (tag,))
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
921
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
922 for line in g:
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
923 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
924
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
925 def _dump(self, tag, x, lo, hi):
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
926 """Generate comparison results for a same-tagged range."""
41642
a6eb6acfe04a Merged revisions 55007-55179 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41554
diff changeset
927 for i in range(lo, hi):
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
928 yield '%s %s' % (tag, x[i])
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
929
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
930 def _plain_replace(self, a, alo, ahi, b, blo, bhi):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
931 assert alo < ahi and blo < bhi
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
932 # dump the shorter block first -- reduces the burden on short-term
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
933 # memory if the blocks are of very different sizes
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
934 if bhi - blo < ahi - alo:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
935 first = self._dump('+', b, blo, bhi)
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
936 second = self._dump('-', a, alo, ahi)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
937 else:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
938 first = self._dump('-', a, alo, ahi)
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
939 second = self._dump('+', b, blo, bhi)
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
940
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
941 for g in first, second:
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
942 for line in g:
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
943 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
944
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
945 def _fancy_replace(self, a, alo, ahi, b, blo, bhi):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
946 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
947 When replacing one block of lines with another, search the blocks
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
948 for *similar* lines; the best-matching pair (if any) is used as a
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
949 synch point, and intraline difference marking is done on the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
950 similar pair. Lots of work, but often worth it.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
951
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
952 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
953
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
954 >>> d = Differ()
29891
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
955 >>> results = d._fancy_replace(['abcDefghiJkl\n'], 0, 1,
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
956 ... ['abcdefGhijkl\n'], 0, 1)
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
957 >>> print(''.join(results), end="")
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
958 - abcDefghiJkl
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
959 ? ^ ^ ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
960 + abcdefGhijkl
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
961 ? ^ ^ ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
962 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
963
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
964 # don't synch up unless the lines have a similarity score of at
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
965 # least cutoff; best_ratio tracks the best score seen so far
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
966 best_ratio, cutoff = 0.74, 0.75
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
967 cruncher = SequenceMatcher(self.charjunk)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
968 eqi, eqj = None, None # 1st indices of equal lines (if any)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
969
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
970 # search for the pair that matches best without being identical
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
971 # (identical lines must be junk lines, & we don't want to synch up
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
972 # on junk -- unless we have to)
41642
a6eb6acfe04a Merged revisions 55007-55179 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41554
diff changeset
973 for j in range(blo, bhi):
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
974 bj = b[j]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
975 cruncher.set_seq2(bj)
41642
a6eb6acfe04a Merged revisions 55007-55179 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41554
diff changeset
976 for i in range(alo, ahi):
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
977 ai = a[i]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
978 if ai == bj:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
979 if eqi is None:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
980 eqi, eqj = i, j
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
981 continue
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
982 cruncher.set_seq1(ai)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
983 # computing similarity is expensive, so use the quick
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
984 # upper bounds first -- have seen this speed up messy
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
985 # compares by a factor of 3.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
986 # note that ratio() is only expensive to compute the first
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
987 # time it's called on a sequence pair; the expensive part
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
988 # of the computation is cached by cruncher
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
989 if cruncher.real_quick_ratio() > best_ratio and \
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
990 cruncher.quick_ratio() > best_ratio and \
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
991 cruncher.ratio() > best_ratio:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
992 best_ratio, best_i, best_j = cruncher.ratio(), i, j
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
993 if best_ratio < cutoff:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
994 # no non-identical "pretty close" pair
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
995 if eqi is None:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
996 # no identical pair either -- treat it as a straight replace
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
997 for line in self._plain_replace(a, alo, ahi, b, blo, bhi):
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
998 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
999 return
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1000 # no close pair, but an identical pair -- synch up on that
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1001 best_i, best_j, best_ratio = eqi, eqj, 1.0
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1002 else:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1003 # there's a close pair, so forget the identical pair (if any)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1004 eqi = None
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1005
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1006 # a[best_i] very similar to b[best_j]; eqi is None iff they're not
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1007 # identical
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1008
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1009 # pump out diffs from before the synch point
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1010 for line in self._fancy_helper(a, alo, best_i, b, blo, best_j):
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1011 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1012
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1013 # do intraline marking on the synch pair
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1014 aelt, belt = a[best_i], b[best_j]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1015 if eqi is None:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1016 # pump out a '-', '?', '+', '?' quad for the synched lines
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1017 atags = btags = ""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1018 cruncher.set_seqs(aelt, belt)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1019 for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes():
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1020 la, lb = ai2 - ai1, bj2 - bj1
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1021 if tag == 'replace':
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1022 atags += '^' * la
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1023 btags += '^' * lb
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1024 elif tag == 'delete':
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1025 atags += '-' * la
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1026 elif tag == 'insert':
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1027 btags += '+' * lb
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1028 elif tag == 'equal':
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1029 atags += ' ' * la
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1030 btags += ' ' * lb
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1031 else:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 42142
diff changeset
1032 raise ValueError('unknown tag %r' % (tag,))
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1033 for line in self._qformat(aelt, belt, atags, btags):
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1034 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1035 else:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1036 # the synch pair is identical
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1037 yield ' ' + aelt
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1038
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1039 # pump out diffs from after the synch point
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1040 for line in self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi):
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1041 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1042
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1043 def _fancy_helper(self, a, alo, ahi, b, blo, bhi):
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1044 g = []
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1045 if alo < ahi:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1046 if blo < bhi:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1047 g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1048 else:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1049 g = self._dump('-', a, alo, ahi)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1050 elif blo < bhi:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1051 g = self._dump('+', b, blo, bhi)
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1052
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1053 for line in g:
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1054 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1055
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1056 def _qformat(self, aline, bline, atags, btags):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1057 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1058 Format "?" output and deal with leading tabs.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1059
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1060 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1061
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1062 >>> d = Differ()
57417
3a2b149ae66e Merged revisions 76469 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 51776
diff changeset
1063 >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n',
3a2b149ae66e Merged revisions 76469 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 51776
diff changeset
1064 ... ' ^ ^ ^ ', ' ^ ^ ^ ')
40786
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
1065 >>> for line in results: print(repr(line))
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
1066 ...
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1067 '- \tabcDefghiJkl\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1068 '? \t ^ ^ ^\n'
57417
3a2b149ae66e Merged revisions 76469 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 51776
diff changeset
1069 '+ \tabcdefGhijkl\n'
3a2b149ae66e Merged revisions 76469 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 51776
diff changeset
1070 '? \t ^ ^ ^\n'
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1071 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1072
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1073 # Can hurt, but will probably help most of the time.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1074 common = min(_count_leading(aline, "\t"),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1075 _count_leading(bline, "\t"))
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1076 common = min(common, _count_leading(atags[:common], " "))
57417
3a2b149ae66e Merged revisions 76469 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 51776
diff changeset
1077 common = min(common, _count_leading(btags[:common], " "))
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1078 atags = atags[common:].rstrip()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1079 btags = btags[common:].rstrip()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1080
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1081 yield "- " + aline
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1082 if atags:
20240
5c4261e74478 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 20038
diff changeset
1083 yield "? %s%s\n" % ("\t" * common, atags)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1084
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1085 yield "+ " + bline
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1086 if btags:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1087 yield "? %s%s\n" % ("\t" * common, btags)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1088
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1089 # With respect to junk, an earlier version of ndiff simply refused to
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1090 # *start* a match with a junk element. The result was cases like this:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1091 # before: private Thread currentThread;
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1092 # after: private volatile Thread currentThread;
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1093 # If you consider whitespace to be junk, the longest contiguous match
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1094 # not starting with junk is "e Thread currentThread". So ndiff reported
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1095 # that "e volatil" was inserted between the 't' and the 'e' in "private".
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1096 # While an accurate view, to people that's absurd. The current version
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1097 # looks for matching blocks that are entirely junk-free, then extends the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1098 # longest one of those as far as possible but only with matching junk.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1099 # So now "currentThread" is matched, then extended to suck up the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1100 # preceding blank; then "private" is matched, and extended to suck up the
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1101 # following blank; then "Thread" is matched; and finally ndiff reports
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1102 # that "volatile " was inserted before "Thread". The only quibble
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1103 # remaining is that perhaps it was really the case that " volatile"
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1104 # was inserted after "private". I can live with that <wink>.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1105
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1106 import re
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1107
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1108 def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1109 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1110 Return 1 for ignorable line: iff `line` is blank or contains a single '#'.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1111
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1112 Examples:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1113
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1114 >>> IS_LINE_JUNK('\n')
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1115 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1116 >>> IS_LINE_JUNK(' # \n')
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1117 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1118 >>> IS_LINE_JUNK('hello\n')
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1119 False
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1120 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1121
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1122 return pat(line) is not None
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1123
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1124 def IS_CHARACTER_JUNK(ch, ws=" \t"):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1125 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1126 Return 1 for ignorable character: iff `ch` is a space or tab.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1127
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1128 Examples:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1129
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1130 >>> IS_CHARACTER_JUNK(' ')
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1131 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1132 >>> IS_CHARACTER_JUNK('\t')
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1133 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1134 >>> IS_CHARACTER_JUNK('\n')
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1135 False
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1136 >>> IS_CHARACTER_JUNK('x')
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1137 False
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1138 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1139
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1140 return ch in ws
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1141
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1142
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1143 def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1144 tofiledate='', n=3, lineterm='\n'):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1145 r"""
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1146 Compare two sequences of lines; generate the delta as a unified diff.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1147
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1148 Unified diffs are a compact way of showing line changes and a few
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1149 lines of context. The number of context lines is set by 'n' which
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1150 defaults to three.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1151
29517
94ac1d42a420 Fix docstring
Raymond Hettinger <python@rcn.com>
parents: 29384
diff changeset
1152 By default, the diff control lines (those with ---, +++, or @@) are
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1153 created with a trailing newline. This is helpful so that inputs
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1154 created from file.readlines() result in diffs that are suitable for
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1155 file.writelines() since both the inputs and outputs have trailing
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1156 newlines.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1157
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1158 For inputs that do not have trailing newlines, set the lineterm
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1159 argument to "" so that the output will be uniformly newline free.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1160
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1161 The unidiff format normally has a header for filenames and modification
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1162 times. Any or all of these may be specified using strings for
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1163 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. The modification
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1164 times are normally expressed in the format returned by time.ctime().
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1165
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1166 Example:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1167
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1168 >>> for line in unified_diff('one two three four'.split(),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1169 ... 'zero one tree four'.split(), 'Original', 'Current',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1170 ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:20:52 2003',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1171 ... lineterm=''):
40786
0ce14c4ca133 Revert doubly-converted doctests.
Guido van Rossum <guido@python.org>
parents: 40785
diff changeset
1172 ... print(line)
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1173 --- Original Sat Jan 26 23:30:50 1991
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1174 +++ Current Fri Jun 06 10:20:52 2003
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1175 @@ -1,4 +1,4 @@
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1176 +zero
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1177 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1178 -two
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1179 -three
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1180 +tree
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1181 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1182 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1183
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1184 started = False
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1185 for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1186 if not started:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1187 yield '--- %s %s%s' % (fromfile, fromfiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1188 yield '+++ %s %s%s' % (tofile, tofiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1189 started = True
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1190 i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1191 yield "@@ -%d,%d +%d,%d @@%s" % (i1+1, i2-i1, j1+1, j2-j1, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1192 for tag, i1, i2, j1, j2 in group:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1193 if tag == 'equal':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1194 for line in a[i1:i2]:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1195 yield ' ' + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1196 continue
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1197 if tag == 'replace' or tag == 'delete':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1198 for line in a[i1:i2]:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1199 yield '-' + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1200 if tag == 'replace' or tag == 'insert':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1201 for line in b[j1:j2]:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1202 yield '+' + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1203
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1204 # See http://www.unix.org/single_unix_specification/
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1205 def context_diff(a, b, fromfile='', tofile='',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1206 fromfiledate='', tofiledate='', n=3, lineterm='\n'):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1207 r"""
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1208 Compare two sequences of lines; generate the delta as a context diff.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1209
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1210 Context diffs are a compact way of showing line changes and a few
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1211 lines of context. The number of context lines is set by 'n' which
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1212 defaults to three.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1213
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1214 By default, the diff control lines (those with *** or ---) are
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1215 created with a trailing newline. This is helpful so that inputs
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1216 created from file.readlines() result in diffs that are suitable for
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1217 file.writelines() since both the inputs and outputs have trailing
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1218 newlines.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1219
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1220 For inputs that do not have trailing newlines, set the lineterm
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1221 argument to "" so that the output will be uniformly newline free.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1222
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1223 The context diff format normally has a header for filenames and
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1224 modification times. Any or all of these may be specified using
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1225 strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1226 The modification times are normally expressed in the format returned
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1227 by time.ctime(). If not specified, the strings default to blanks.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1228
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1229 Example:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1230
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
1231 >>> print(''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1232 ... 'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1233 ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:22:46 2003')),
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
1234 ... end="")
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1235 *** Original Sat Jan 26 23:30:50 1991
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1236 --- Current Fri Jun 06 10:22:46 2003
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1237 ***************
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1238 *** 1,4 ****
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1239 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1240 ! two
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1241 ! three
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1242 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1243 --- 1,4 ----
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1244 + zero
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1245 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1246 ! tree
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1247 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1248 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1249
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1250 started = False
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1251 prefixmap = {'insert':'+ ', 'delete':'- ', 'replace':'! ', 'equal':' '}
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1252 for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1253 if not started:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1254 yield '*** %s %s%s' % (fromfile, fromfiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1255 yield '--- %s %s%s' % (tofile, tofiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1256 started = True
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1257
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1258 yield '***************%s' % (lineterm,)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1259 if group[-1][2] - group[0][1] >= 2:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1260 yield '*** %d,%d ****%s' % (group[0][1]+1, group[-1][2], lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1261 else:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1262 yield '*** %d ****%s' % (group[-1][2], lineterm)
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1263 visiblechanges = [e for e in group if e[0] in ('replace', 'delete')]
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1264 if visiblechanges:
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1265 for tag, i1, i2, _, _ in group:
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1266 if tag != 'insert':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1267 for line in a[i1:i2]:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1268 yield prefixmap[tag] + line
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1269
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1270 if group[-1][4] - group[0][3] >= 2:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1271 yield '--- %d,%d ----%s' % (group[0][3]+1, group[-1][4], lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1272 else:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1273 yield '--- %d ----%s' % (group[-1][4], lineterm)
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1274 visiblechanges = [e for e in group if e[0] in ('replace', 'insert')]
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1275 if visiblechanges:
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1276 for tag, _, _, j1, j2 in group:
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1277 if tag != 'delete':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1278 for line in b[j1:j2]:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1279 yield prefixmap[tag] + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1280
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
1281 def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK):
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1282 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1283 Compare `a` and `b` (lists of strings); return a `Differ`-style delta.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1284
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1285 Optional keyword parameters `linejunk` and `charjunk` are for filter
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1286 functions (or None):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1287
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1288 - linejunk: A function that should accept a single string argument, and
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
1289 return true iff the string is junk. The default is None, and is
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
1290 recommended; as of Python 2.3, an adaptive notion of "noise" lines is
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
1291 used that does a good job on its own.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1292
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1293 - charjunk: A function that should accept a string of length 1. The
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1294 default is module-level function IS_CHARACTER_JUNK, which filters out
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1295 whitespace characters (a blank or tab; note: bad idea to include newline
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1296 in this!).
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1297
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1298 Tools/scripts/ndiff.py is a command-line front-end to this function.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1299
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1300 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1301
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1302 >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1303 ... 'ore\ntree\nemu\n'.splitlines(1))
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
1304 >>> print(''.join(diff), end="")
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1305 - one
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1306 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1307 + ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1308 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1309 - two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1310 - three
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1311 ? -
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1312 + tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1313 + emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1314 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1315 return Differ(linejunk, charjunk).compare(a, b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1316
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1317 def _mdiff(fromlines, tolines, context=None, linejunk=None,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1318 charjunk=IS_CHARACTER_JUNK):
40582
67287ca4e1e8 Merged revisions 53005-53303 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 39627
diff changeset
1319 r"""Returns generator yielding marked up from/to side by side differences.
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1320
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1321 Arguments:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1322 fromlines -- list of text lines to compared to tolines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1323 tolines -- list of text lines to be compared to fromlines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1324 context -- number of context lines to display on each side of difference,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1325 if None, all from/to text lines will be generated.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1326 linejunk -- passed on to ndiff (see ndiff documentation)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1327 charjunk -- passed on to ndiff (see ndiff documentation)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1328
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1329 This function returns an interator which returns a tuple:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1330 (from line tuple, to line tuple, boolean flag)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1331
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1332 from/to line tuple -- (line num, line text)
51776
d06a3ebf306f Merged revisions 69846 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 44643
diff changeset
1333 line num -- integer or None (to indicate a context separation)
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1334 line text -- original line text with following markers inserted:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1335 '\0+' -- marks start of added text
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1336 '\0-' -- marks start of deleted text
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1337 '\0^' -- marks start of changed text
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1338 '\1' -- marks end of added/deleted/changed text
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1339
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1340 boolean flag -- None indicates context separation, True indicates
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1341 either "from" or "to" line contains a change, otherwise False.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1342
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1343 This function/iterator was originally developed to generate side by side
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1344 file difference for making HTML pages (see HtmlDiff class for example
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1345 usage).
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1346
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1347 Note, this function utilizes the ndiff function to generate the side by
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1348 side difference markup. Optional ndiff arguments may be passed to this
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1349 function and they in turn will be passed to ndiff.
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1350 """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1351 import re
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1352
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1353 # regular expression for finding intraline change indices
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1354 change_re = re.compile('(\++|\-+|\^+)')
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1355
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1356 # create the difference iterator to generate the differences
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1357 diff_lines_iterator = ndiff(fromlines,tolines,linejunk,charjunk)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1358
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1359 def _make_line(lines, format_key, side, num_lines=[0,0]):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1360 """Returns line of text with user's change markup and line formatting.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1361
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1362 lines -- list of lines from the ndiff generator to produce a line of
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1363 text from. When producing the line of text to return, the
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1364 lines used are removed from this list.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1365 format_key -- '+' return first line in list with "add" markup around
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1366 the entire line.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1367 '-' return first line in list with "delete" markup around
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1368 the entire line.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1369 '?' return first line in list with add/delete/change
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1370 intraline markup (indices obtained from second line)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1371 None return first line in list with no markup
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1372 side -- indice into the num_lines list (0=from,1=to)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1373 num_lines -- from/to current line number. This is NOT intended to be a
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1374 passed parameter. It is present as a keyword argument to
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1375 maintain memory of the current line numbers between calls
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1376 of this function.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1377
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1378 Note, this function is purposefully not defined at the module scope so
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1379 that data it needs from its parent function (within whose context it
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1380 is defined) does not need to be of module scope.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1381 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1382 num_lines[side] += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1383 # Handle case where no user markup is to be added, just return line of
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1384 # text with user's line format to allow for usage of the line number.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1385 if format_key is None:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1386 return (num_lines[side],lines.pop(0)[2:])
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1387 # Handle case of intraline changes
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1388 if format_key == '?':
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1389 text, markers = lines.pop(0), lines.pop(0)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1390 # find intraline changes (store change type and indices in tuples)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1391 sub_info = []
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1392 def record_sub_info(match_object,sub_info=sub_info):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1393 sub_info.append([match_object.group(1)[0],match_object.span()])
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1394 return match_object.group(1)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1395 change_re.sub(record_sub_info,markers)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1396 # process each tuple inserting our special marks that won't be
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1397 # noticed by an xml/html escaper.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1398 for key,(begin,end) in sub_info[::-1]:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1399 text = text[0:begin]+'\0'+key+text[begin:end]+'\1'+text[end:]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1400 text = text[2:]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1401 # Handle case of add/delete entire line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1402 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1403 text = lines.pop(0)[2:]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1404 # if line of text is just a newline, insert a space so there is
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1405 # something for the user to highlight and see.
33981
ec29955b8543 SF bug 1054821: difflib HtmlDiff() extra space on inserted 1 character lines
Tim Peters <tim.peters@gmail.com>
parents: 33448
diff changeset
1406 if not text:
ec29955b8543 SF bug 1054821: difflib HtmlDiff() extra space on inserted 1 character lines
Tim Peters <tim.peters@gmail.com>
parents: 33448
diff changeset
1407 text = ' '
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1408 # insert marks that won't be noticed by an xml/html escaper.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1409 text = '\0' + format_key + text + '\1'
35276
4adbd331d335 Fix all wrong instances of "it's".
Georg Brandl <georg@python.org>
parents: 33981
diff changeset
1410 # Return line of text, first allow user's line formatter to do its
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1411 # thing (such as adding the line number) then replace the special
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1412 # marks with what the user's change markup.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1413 return (num_lines[side],text)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1414
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1415 def _line_iterator():
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1416 """Yields from/to lines of text with a change indication.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1417
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1418 This function is an iterator. It itself pulls lines from a
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1419 differencing iterator, processes them and yields them. When it can
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1420 it yields both a "from" and a "to" line, otherwise it will yield one
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1421 or the other. In addition to yielding the lines of from/to text, a
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1422 boolean flag is yielded to indicate if the text line(s) have
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1423 differences in them.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1424
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1425 Note, this function is purposefully not defined at the module scope so
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1426 that data it needs from its parent function (within whose context it
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1427 is defined) does not need to be of module scope.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1428 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1429 lines = []
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1430 num_blanks_pending, num_blanks_to_yield = 0, 0
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1431 while True:
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1432 # Load up next 4 lines so we can look ahead, create strings which
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1433 # are a concatenation of the first character of each of the 4 lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1434 # so we can do some very readable comparisons.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1435 while len(lines) < 4:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1436 try:
41501
0c5019afc55b PEP 3114: rename .next() to .__next__() and add next() builtin.
Georg Brandl <georg@python.org>
parents: 40809
diff changeset
1437 lines.append(next(diff_lines_iterator))
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1438 except StopIteration:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1439 lines.append('X')
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1440 s = ''.join([line[0] for line in lines])
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1441 if s.startswith('X'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1442 # When no more lines, pump out any remaining blank lines so the
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1443 # corresponding add/delete lines get a matching blank line so
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1444 # all line pairs get yielded at the next level.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1445 num_blanks_to_yield = num_blanks_pending
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1446 elif s.startswith('-?+?'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1447 # simple intraline change
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1448 yield _make_line(lines,'?',0), _make_line(lines,'?',1), True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1449 continue
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1450 elif s.startswith('--++'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1451 # in delete block, add block coming: we do NOT want to get
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1452 # caught up on blank lines yet, just process the delete line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1453 num_blanks_pending -= 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1454 yield _make_line(lines,'-',0), None, True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1455 continue
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
1456 elif s.startswith(('--?+', '--+', '- ')):
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1457 # in delete block and see a intraline change or unchanged line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1458 # coming: yield the delete line and then blanks
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1459 from_line,to_line = _make_line(lines,'-',0), None
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1460 num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1461 elif s.startswith('-+?'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1462 # intraline change
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1463 yield _make_line(lines,None,0), _make_line(lines,'?',1), True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1464 continue
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1465 elif s.startswith('-?+'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1466 # intraline change
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1467 yield _make_line(lines,'?',0), _make_line(lines,None,1), True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1468 continue
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1469 elif s.startswith('-'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1470 # delete FROM line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1471 num_blanks_pending -= 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1472 yield _make_line(lines,'-',0), None, True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1473 continue
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1474 elif s.startswith('+--'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1475 # in add block, delete block coming: we do NOT want to get
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1476 # caught up on blank lines yet, just process the add line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1477 num_blanks_pending += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1478 yield None, _make_line(lines,'+',1), True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1479 continue
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
1480 elif s.startswith(('+ ', '+-')):
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1481 # will be leaving an add block: yield blanks then add line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1482 from_line, to_line = None, _make_line(lines,'+',1)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1483 num_blanks_to_yield,num_blanks_pending = num_blanks_pending+1,0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1484 elif s.startswith('+'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1485 # inside an add block, yield the add line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1486 num_blanks_pending += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1487 yield None, _make_line(lines,'+',1), True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1488 continue
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1489 elif s.startswith(' '):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1490 # unchanged text, yield it to both sides
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1491 yield _make_line(lines[:],None,0),_make_line(lines,None,1),False
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1492 continue
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1493 # Catch up on the blank lines so when we yield the next from/to
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1494 # pair, they are lined up.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1495 while(num_blanks_to_yield < 0):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1496 num_blanks_to_yield += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1497 yield None,('','\n'),True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1498 while(num_blanks_to_yield > 0):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1499 num_blanks_to_yield -= 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1500 yield ('','\n'),None,True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1501 if s.startswith('X'):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1502 raise StopIteration
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1503 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1504 yield from_line,to_line,True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1505
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1506 def _line_pair_iterator():
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1507 """Yields from/to lines of text with a change indication.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1508
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1509 This function is an iterator. It itself pulls lines from the line
35276
4adbd331d335 Fix all wrong instances of "it's".
Georg Brandl <georg@python.org>
parents: 33981
diff changeset
1510 iterator. Its difference from that iterator is that this function
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1511 always yields a pair of from/to text lines (with the change
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1512 indication). If necessary it will collect single from/to lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1513 until it has a matching pair from/to pair to yield.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1514
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1515 Note, this function is purposefully not defined at the module scope so
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1516 that data it needs from its parent function (within whose context it
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1517 is defined) does not need to be of module scope.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1518 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1519 line_iterator = _line_iterator()
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1520 fromlines,tolines=[],[]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1521 while True:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1522 # Collecting lines of text until we have a from/to pair
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1523 while (len(fromlines)==0 or len(tolines)==0):
41501
0c5019afc55b PEP 3114: rename .next() to .__next__() and add next() builtin.
Georg Brandl <georg@python.org>
parents: 40809
diff changeset
1524 from_line, to_line, found_diff = next(line_iterator)
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1525 if from_line is not None:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1526 fromlines.append((from_line,found_diff))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1527 if to_line is not None:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1528 tolines.append((to_line,found_diff))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1529 # Once we have a pair, remove them from the collection and yield it
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1530 from_line, fromDiff = fromlines.pop(0)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1531 to_line, to_diff = tolines.pop(0)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1532 yield (from_line,to_line,fromDiff or to_diff)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1533
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1534 # Handle case where user does not want context differencing, just yield
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1535 # them up without doing anything else with them.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1536 line_pair_iterator = _line_pair_iterator()
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1537 if context is None:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1538 while True:
41501
0c5019afc55b PEP 3114: rename .next() to .__next__() and add next() builtin.
Georg Brandl <georg@python.org>
parents: 40809
diff changeset
1539 yield next(line_pair_iterator)
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1540 # Handle case where user wants context differencing. We must do some
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1541 # storage of lines until we know for sure that they are to be yielded.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1542 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1543 context += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1544 lines_to_write = 0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1545 while True:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1546 # Store lines up until we find a difference, note use of a
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1547 # circular queue because we only need to keep around what
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1548 # we need for context.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1549 index, contextLines = 0, [None]*(context)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1550 found_diff = False
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1551 while(found_diff is False):
41501
0c5019afc55b PEP 3114: rename .next() to .__next__() and add next() builtin.
Georg Brandl <georg@python.org>
parents: 40809
diff changeset
1552 from_line, to_line, found_diff = next(line_pair_iterator)
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1553 i = index % context
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1554 contextLines[i] = (from_line, to_line, found_diff)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1555 index += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1556 # Yield lines that we have collected so far, but first yield
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1557 # the user's separator.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1558 if index > context:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1559 yield None, None, None
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1560 lines_to_write = context
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1561 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1562 lines_to_write = index
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1563 index = 0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1564 while(lines_to_write):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1565 i = index % context
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1566 index += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1567 yield contextLines[i]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1568 lines_to_write -= 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1569 # Now yield the context lines after the change
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1570 lines_to_write = context-1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1571 while(lines_to_write):
41501
0c5019afc55b PEP 3114: rename .next() to .__next__() and add next() builtin.
Georg Brandl <georg@python.org>
parents: 40809
diff changeset
1572 from_line, to_line, found_diff = next(line_pair_iterator)
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1573 # If another change within the context, extend the context
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1574 if found_diff:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1575 lines_to_write = context-1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1576 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1577 lines_to_write -= 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1578 yield from_line, to_line, found_diff
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1579
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1580
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1581 _file_template = """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1582 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1583 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1584
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1585 <html>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1586
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1587 <head>
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1588 <meta http-equiv="Content-Type"
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1589 content="text/html; charset=ISO-8859-1" />
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1590 <title></title>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1591 <style type="text/css">%(styles)s
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1592 </style>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1593 </head>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1594
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1595 <body>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1596 %(table)s%(legend)s
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1597 </body>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1598
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1599 </html>"""
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1600
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1601 _styles = """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1602 table.diff {font-family:Courier; border:medium;}
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1603 .diff_header {background-color:#e0e0e0}
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1604 td.diff_header {text-align:right}
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1605 .diff_next {background-color:#c0c0c0}
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1606 .diff_add {background-color:#aaffaa}
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1607 .diff_chg {background-color:#ffff77}
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1608 .diff_sub {background-color:#ffaaaa}"""
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1609
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1610 _table_template = """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1611 <table class="diff" id="difflib_chg_%(prefix)s_top"
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1612 cellspacing="0" cellpadding="0" rules="groups" >
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1613 <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1614 <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1615 %(header_row)s
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1616 <tbody>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1617 %(data_rows)s </tbody>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1618 </table>"""
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1619
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1620 _legend = """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1621 <table class="diff" summary="Legends">
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1622 <tr> <th colspan="2"> Legends </th> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1623 <tr> <td> <table border="" summary="Colors">
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1624 <tr><th> Colors </th> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1625 <tr><td class="diff_add">&nbsp;Added&nbsp;</td></tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1626 <tr><td class="diff_chg">Changed</td> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1627 <tr><td class="diff_sub">Deleted</td> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1628 </table></td>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1629 <td> <table border="" summary="Links">
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1630 <tr><th colspan="2"> Links </th> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1631 <tr><td>(f)irst change</td> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1632 <tr><td>(n)ext change</td> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1633 <tr><td>(t)op</td> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1634 </table></td> </tr>
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1635 </table>"""
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1636
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1637 class HtmlDiff(object):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1638 """For producing HTML side by side comparison with change highlights.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1639
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1640 This class can be used to create an HTML table (or a complete HTML file
33448
5570fae1f01c Typo fix: 'comparisions' is not a word
Andrew M. Kuchling <amk@amk.ca>
parents: 33326
diff changeset
1641 containing the table) showing a side by side, line by line comparison
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1642 of text with inter-line and intra-line change highlights. The table can
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1643 be generated in either full or contextual difference mode.
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1644
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1645 The following methods are provided for HTML generation:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1646
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1647 make_table -- generates HTML for a single side by side table
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1648 make_file -- generates complete HTML file with a single side by side table
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1649
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1650 See tools/scripts/diff.py for an example usage of this class.
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1651 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1652
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1653 _file_template = _file_template
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1654 _styles = _styles
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1655 _table_template = _table_template
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1656 _legend = _legend
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1657 _default_prefix = 0
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1658
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1659 def __init__(self,tabsize=8,wrapcolumn=None,linejunk=None,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1660 charjunk=IS_CHARACTER_JUNK):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1661 """HtmlDiff instance initializer
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1662
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1663 Arguments:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1664 tabsize -- tab stop spacing, defaults to 8.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1665 wrapcolumn -- column number where lines are broken and wrapped,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1666 defaults to None where lines are not wrapped.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1667 linejunk,charjunk -- keyword arguments passed into ndiff() (used to by
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1668 HtmlDiff() to generate the side by side HTML differences). See
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1669 ndiff() documentation for argument default values and descriptions.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1670 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1671 self._tabsize = tabsize
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1672 self._wrapcolumn = wrapcolumn
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1673 self._linejunk = linejunk
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1674 self._charjunk = charjunk
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1675
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1676 def make_file(self,fromlines,tolines,fromdesc='',todesc='',context=False,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1677 numlines=5):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1678 """Returns HTML file of side by side comparison with change highlights
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1679
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1680 Arguments:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1681 fromlines -- list of "from" lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1682 tolines -- list of "to" lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1683 fromdesc -- "from" file column header string
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1684 todesc -- "to" file column header string
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1685 context -- set to True for contextual differences (defaults to False
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1686 which shows full differences).
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1687 numlines -- number of context lines. When context is set True,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1688 controls number of lines displayed before and after the change.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1689 When context is False, controls the number of lines to place
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1690 the "next" link anchors before the next change (so click of
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1691 "next" link jumps to just before the change).
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1692 """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1693
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1694 return self._file_template % dict(
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1695 styles = self._styles,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1696 legend = self._legend,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1697 table = self.make_table(fromlines,tolines,fromdesc,todesc,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1698 context=context,numlines=numlines))
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1699
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1700 def _tab_newline_replace(self,fromlines,tolines):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1701 """Returns from/to line lists with tabs expanded and newlines removed.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1702
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1703 Instead of tab characters being replaced by the number of spaces
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1704 needed to fill in to the next tab stop, this function will fill
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1705 the space with tab characters. This is done so that the difference
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1706 algorithms can identify changes in a file when tabs are replaced by
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1707 spaces and vice versa. At the end of the HTML generation, the tab
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1708 characters will be replaced with a nonbreakable space.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1709 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1710 def expand_tabs(line):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1711 # hide real spaces
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1712 line = line.replace(' ','\0')
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1713 # expand tabs into spaces
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1714 line = line.expandtabs(self._tabsize)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1715 # relace spaces from expanded tabs back into tab characters
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1716 # (we'll replace them with markup after we do differencing)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1717 line = line.replace(' ','\t')
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1718 return line.replace('\0',' ').rstrip('\n')
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1719 fromlines = [expand_tabs(line) for line in fromlines]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1720 tolines = [expand_tabs(line) for line in tolines]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1721 return fromlines,tolines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1722
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1723 def _split_line(self,data_list,line_num,text):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1724 """Builds list of text lines by splitting text lines at wrap point
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1725
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1726 This function will determine if the input text line needs to be
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1727 wrapped (split) into separate lines. If so, the first wrap point
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1728 will be determined and the first line appended to the output
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1729 text line list. This function is used recursively to handle
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1730 the second part of the split line to further split it.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1731 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1732 # if blank line or context separator, just add it to the output list
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1733 if not line_num:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1734 data_list.append((line_num,text))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1735 return
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1736
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1737 # if line text doesn't need wrapping, just add it to the output list
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1738 size = len(text)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1739 max = self._wrapcolumn
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1740 if (size <= max) or ((size -(text.count('\0')*3)) <= max):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1741 data_list.append((line_num,text))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1742 return
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1743
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1744 # scan text looking for the wrap point, keeping track if the wrap
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1745 # point is inside markers
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1746 i = 0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1747 n = 0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1748 mark = ''
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1749 while n < max and i < size:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1750 if text[i] == '\0':
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1751 i += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1752 mark = text[i]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1753 i += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1754 elif text[i] == '\1':
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1755 i += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1756 mark = ''
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1757 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1758 i += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1759 n += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1760
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1761 # wrap point is inside text, break it up into separate lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1762 line1 = text[:i]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1763 line2 = text[i:]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1764
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1765 # if wrap point is inside markers, place end marker at end of first
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1766 # line and start marker at beginning of second line because each
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1767 # line will have its own table tag markup around it.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1768 if mark:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1769 line1 = line1 + '\1'
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1770 line2 = '\0' + mark + line2
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1771
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1772 # tack on first line onto the output list
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1773 data_list.append((line_num,line1))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1774
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1775 # use this routine again to wrap the remaining text
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1776 self._split_line(data_list,'>',line2)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1777
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1778 def _line_wrapper(self,diffs):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1779 """Returns iterator that splits (wraps) mdiff text lines"""
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1780
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1781 # pull from/to data and flags from mdiff iterator
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1782 for fromdata,todata,flag in diffs:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1783 # check for context separators and pass them through
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1784 if flag is None:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1785 yield fromdata,todata,flag
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1786 continue
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1787 (fromline,fromtext),(toline,totext) = fromdata,todata
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1788 # for each from/to line split it at the wrap column to form
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1789 # list of text lines.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1790 fromlist,tolist = [],[]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1791 self._split_line(fromlist,fromline,fromtext)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1792 self._split_line(tolist,toline,totext)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1793 # yield from/to line in pairs inserting blank lines as
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1794 # necessary when one side has more wrapped lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1795 while fromlist or tolist:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1796 if fromlist:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1797 fromdata = fromlist.pop(0)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1798 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1799 fromdata = ('',' ')
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1800 if tolist:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1801 todata = tolist.pop(0)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1802 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1803 todata = ('',' ')
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1804 yield fromdata,todata,flag
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1805
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1806 def _collect_lines(self,diffs):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1807 """Collects mdiff output into separate lists
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1808
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1809 Before storing the mdiff from/to data into a list, it is converted
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1810 into a single line of text with HTML markup.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1811 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1812
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1813 fromlist,tolist,flaglist = [],[],[]
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1814 # pull from/to data and flags from mdiff style iterator
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1815 for fromdata,todata,flag in diffs:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1816 try:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1817 # store HTML markup of the lines into the lists
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1818 fromlist.append(self._format_line(0,flag,*fromdata))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1819 tolist.append(self._format_line(1,flag,*todata))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1820 except TypeError:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1821 # exceptions occur for lines where context separators go
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1822 fromlist.append(None)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1823 tolist.append(None)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1824 flaglist.append(flag)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1825 return fromlist,tolist,flaglist
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1826
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1827 def _format_line(self,side,flag,linenum,text):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1828 """Returns HTML markup of "from" / "to" text lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1829
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1830 side -- 0 or 1 indicating "from" or "to" text
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1831 flag -- indicates if difference on line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1832 linenum -- line number (used for line number column)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1833 text -- line text to be marked up
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1834 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1835 try:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1836 linenum = '%d' % linenum
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1837 id = ' id="%s%s"' % (self._prefix[side],linenum)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1838 except TypeError:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1839 # handle blank lines where linenum is '>' or ''
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1840 id = ''
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1841 # replace those things that would get confused with HTML symbols
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1842 text=text.replace("&","&amp;").replace(">","&gt;").replace("<","&lt;")
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1843
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1844 # make space non-breakable so they don't get compressed or line wrapped
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1845 text = text.replace(' ','&nbsp;').rstrip()
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1846
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1847 return '<td class="diff_header"%s>%s</td><td nowrap="nowrap">%s</td>' \
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1848 % (id,linenum,text)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1849
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1850 def _make_prefix(self):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1851 """Create unique anchor prefixes"""
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1852
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1853 # Generate a unique anchor prefix so multiple tables
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1854 # can exist on the same HTML page without conflicts.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1855 fromprefix = "from%d_" % HtmlDiff._default_prefix
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1856 toprefix = "to%d_" % HtmlDiff._default_prefix
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1857 HtmlDiff._default_prefix += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1858 # store prefixes so line format method has access
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1859 self._prefix = [fromprefix,toprefix]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1860
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1861 def _convert_flags(self,fromlist,tolist,flaglist,context,numlines):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1862 """Makes list of "next" links"""
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1863
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1864 # all anchor names will be generated using the unique "to" prefix
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1865 toprefix = self._prefix[1]
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1866
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1867 # process change flags, generating middle column of next anchors/links
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1868 next_id = ['']*len(flaglist)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1869 next_href = ['']*len(flaglist)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1870 num_chg, in_change = 0, False
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1871 last = 0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1872 for i,flag in enumerate(flaglist):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1873 if flag:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1874 if not in_change:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1875 in_change = True
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1876 last = i
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1877 # at the beginning of a change, drop an anchor a few lines
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1878 # (the context lines) before the change for the previous
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1879 # link
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1880 i = max([0,i-numlines])
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1881 next_id[i] = ' id="difflib_chg_%s_%d"' % (toprefix,num_chg)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1882 # at the beginning of a change, drop a link to the next
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1883 # change
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1884 num_chg += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1885 next_href[last] = '<a href="#difflib_chg_%s_%d">n</a>' % (
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1886 toprefix,num_chg)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1887 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1888 in_change = False
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1889 # check for cases where there is no content to avoid exceptions
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1890 if not flaglist:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1891 flaglist = [False]
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1892 next_id = ['']
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1893 next_href = ['']
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1894 last = 0
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1895 if context:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1896 fromlist = ['<td></td><td>&nbsp;No Differences Found&nbsp;</td>']
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1897 tolist = fromlist
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1898 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1899 fromlist = tolist = ['<td></td><td>&nbsp;Empty File&nbsp;</td>']
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1900 # if not a change on first line, drop a link
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1901 if not flaglist[0]:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1902 next_href[0] = '<a href="#difflib_chg_%s_0">f</a>' % toprefix
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1903 # redo the last link to link to the top
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1904 next_href[last] = '<a href="#difflib_chg_%s_top">t</a>' % (toprefix)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1905
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1906 return fromlist,tolist,flaglist,next_href,next_id
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1907
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1908 def make_table(self,fromlines,tolines,fromdesc='',todesc='',context=False,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1909 numlines=5):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1910 """Returns HTML table of side by side comparison with change highlights
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1911
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1912 Arguments:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1913 fromlines -- list of "from" lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1914 tolines -- list of "to" lines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1915 fromdesc -- "from" file column header string
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1916 todesc -- "to" file column header string
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1917 context -- set to True for contextual differences (defaults to False
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1918 which shows full differences).
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1919 numlines -- number of context lines. When context is set True,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1920 controls number of lines displayed before and after the change.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1921 When context is False, controls the number of lines to place
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1922 the "next" link anchors before the next change (so click of
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1923 "next" link jumps to just before the change).
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1924 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1925
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1926 # make unique anchor prefixes so that multiple tables may exist
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1927 # on the same page without conflict.
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1928 self._make_prefix()
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1929
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1930 # change tabs to spaces before it gets more difficult after we insert
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1931 # markkup
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1932 fromlines,tolines = self._tab_newline_replace(fromlines,tolines)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1933
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1934 # create diffs iterator which generates side by side from/to data
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1935 if context:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1936 context_lines = numlines
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1937 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1938 context_lines = None
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1939 diffs = _mdiff(fromlines,tolines,context_lines,linejunk=self._linejunk,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1940 charjunk=self._charjunk)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1941
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1942 # set up iterator to wrap lines that exceed desired width
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1943 if self._wrapcolumn:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1944 diffs = self._line_wrapper(diffs)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1945
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1946 # collect up from/to lines and flags into lists (also format the lines)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1947 fromlist,tolist,flaglist = self._collect_lines(diffs)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1948
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1949 # process change flags, generating middle column of next anchors/links
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1950 fromlist,tolist,flaglist,next_href,next_id = self._convert_flags(
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1951 fromlist,tolist,flaglist,context,numlines)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1952
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41501
diff changeset
1953 s = []
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1954 fmt = ' <tr><td class="diff_next"%s>%s</td>%s' + \
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1955 '<td class="diff_next">%s</td>%s</tr>\n'
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1956 for i in range(len(flaglist)):
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1957 if flaglist[i] is None:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1958 # mdiff yields None on separator lines skip the bogus ones
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1959 # generated for the first line
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1960 if i > 0:
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41501
diff changeset
1961 s.append(' </tbody> \n <tbody>\n')
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1962 else:
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41501
diff changeset
1963 s.append( fmt % (next_id[i],next_href[i],fromlist[i],
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1964 next_href[i],tolist[i]))
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1965 if fromdesc or todesc:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1966 header_row = '<thead><tr>%s%s%s%s</tr></thead>' % (
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1967 '<th class="diff_next"><br /></th>',
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1968 '<th colspan="2" class="diff_header">%s</th>' % fromdesc,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1969 '<th class="diff_next"><br /></th>',
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1970 '<th colspan="2" class="diff_header">%s</th>' % todesc)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1971 else:
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1972 header_row = ''
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1973
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1974 table = self._table_template % dict(
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41501
diff changeset
1975 data_rows=''.join(s),
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1976 header_row=header_row,
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1977 prefix=self._prefix[1])
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1978
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1979 return table.replace('\0+','<span class="diff_add">'). \
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1980 replace('\0-','<span class="diff_sub">'). \
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1981 replace('\0^','<span class="diff_chg">'). \
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1982 replace('\1','</span>'). \
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1983 replace('\t','&nbsp;')
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1984
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1985 del re
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1986
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1987 def restore(delta, which):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1988 r"""
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1989 Generate one of the two sequences that generated a delta.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1990
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1991 Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1992 lines originating from file 1 or 2 (parameter `which`), stripping off line
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1993 prefixes.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1994
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1995 Examples:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1996
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1997 >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1998 ... 'ore\ntree\nemu\n'.splitlines(1))
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1999 >>> diff = list(diff)
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
2000 >>> print(''.join(restore(diff, 1)), end="")
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2001 one
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2002 two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2003 three
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40582
diff changeset
2004 >>> print(''.join(restore(diff, 2)), end="")
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2005 ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2006 tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2007 emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2008 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2009 try:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2010 tag = {1: "- ", 2: "+ "}[int(which)]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2011 except KeyError:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 42142
diff changeset
2012 raise ValueError('unknown delta choice (must be 1 or 2): %r'
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2013 % which)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2014 prefixes = (" ", tag)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2015 for line in delta:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2016 if line[:2] in prefixes:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
2017 yield line[2:]
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2018
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2019 def _test():
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2020 import doctest, difflib
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2021 return doctest.testmod(difflib)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2022
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2023 if __name__ == "__main__":
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2024 _test()