annotate Lib/difflib.py @ 80661:94de77bd0b4b 2.7

Issue #16194: document imp.load_dynamic problems when read several extension modules from the same binary object file.
author Andrew Svetlov <andrew.svetlov@gmail.com>
date Thu, 29 Nov 2012 19:51:28 +0200
parents 09459397f807
children d234dd21374a
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',
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
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
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
diff changeset
36 from collections import namedtuple as _namedtuple
48205
bc6a3572bc89 Use functools.reduce() in difflib instead of __builtin__.reduce() to silence
Brett Cannon <bcannon@gmail.com>
parents: 47821
diff changeset
37 from functools import reduce
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
diff changeset
38
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
diff changeset
39 Match = _namedtuple('Match', 'a b size')
32339
408a40e65247 Apply heapq.nlargest() to find best matches.
Raymond Hettinger <python@rcn.com>
parents: 31515
diff changeset
40
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
41 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
42 if length:
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
43 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
44 return 1.0
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
45
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
46 class SequenceMatcher:
19200
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 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
49 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
50 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
51 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
52 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
53 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
54 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
55 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
56 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
57 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
58 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
59
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
60 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
61 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
62 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
63 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
64 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
65 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
66 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
67 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
68 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
69 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
70 "junk" <wink>.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
71
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
72 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
73
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
74 >>> 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
75 ... "private Thread currentThread;",
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
76 ... "private volatile Thread currentThread;")
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
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
79 .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
80 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
81 sequences are close matches:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
82
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
83 >>> print round(s.ratio(), 3)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
84 0.866
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
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
87 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
88 .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
89
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
90 >>> for block in s.get_matching_blocks():
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
91 ... print "a[%d] and b[%d] match for %d elements" % block
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
92 a[0] and b[0] match for 8 elements
38811
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
93 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
94 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
95
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
96 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
97 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
98 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
99
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
100 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
101 use .get_opcodes():
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
102
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
103 >>> for opcode in s.get_opcodes():
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
104 ... print "%6s a[%d:%d] b[%d:%d]" % opcode
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
105 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
106 insert a[8:8] b[8:17]
38811
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
107 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
108
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
109 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
110 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
111 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
112
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
113 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
114 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
115
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
116 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
117 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
118 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
119 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
120
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
121 Methods:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
122
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
123 __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
124 Construct a SequenceMatcher.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
125
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
126 set_seqs(a, b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
127 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
128
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
129 set_seq1(a)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
130 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
131
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
132 set_seq2(b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
133 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
134
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
135 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
136 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
137
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
138 get_matching_blocks()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
139 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
140
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
141 get_opcodes()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
142 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
143
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
144 ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
145 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
146
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
147 quick_ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
148 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
149
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
150 real_quick_ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
151 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
152 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
153
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
154 def __init__(self, isjunk=None, a='', b='', autojunk=True):
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
155 """Construct a SequenceMatcher.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
156
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
157 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
158 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
159 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
160 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
161 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
162 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
163 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
164
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
165 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
166 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
167 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
168
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
169 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
170 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
171 also .set_seqs() and .set_seq2().
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
172
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
173 Optional arg autojunk should be set to False to disable the
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
174 "automatic junk heuristic" that treats popular elements as junk
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
175 (see module documentation for more information).
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
176 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
177
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
178 # Members:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
179 # a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
180 # first sequence
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
181 # b
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
182 # 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
183 # 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
184 # b2j
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
185 # 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
186 # 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
187 # fullbcount
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
188 # 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
189 # 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
190 # 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
191 # matching_blocks
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
192 # 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
193 # 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
194 # 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
195 # opcodes
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
196 # 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
197 # one of
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
198 # '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
199 # '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
200 # '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
201 # '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
202 # isjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
203 # 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
204 # 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
205 # 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
206 # 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
207 # 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
208 # isbjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
209 # for x in b, isbjunk(x) == isjunk(x) but much faster;
47821
0af6f0300eaf Issue 3189: Py3k DeprecationWarning in difflib
Raymond Hettinger <python@rcn.com>
parents: 44633
diff changeset
210 # 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
211 # 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
212 # isbpopular
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
213 # for x in b, isbpopular(x) is true iff b is reasonably long
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
214 # (at least 200 elements) and x accounts for more than 1 + 1% of
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
215 # its elements (when autojunk is enabled).
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
216 # 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
217
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
218 self.isjunk = isjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
219 self.a = self.b = None
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
220 self.autojunk = autojunk
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
221 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
222
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
223 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
224 """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
225
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
226 >>> s = SequenceMatcher()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
227 >>> 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
228 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
229 0.75
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
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
232 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
233 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
234
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
235 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
236 """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
237
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
238 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
239
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
240 >>> 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
241 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
242 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
243 >>> 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
244 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
245 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
246 >>>
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 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
249 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
250 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
251 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
252
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
253 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
254 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
255
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
256 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
257 return
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
258 self.a = a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
259 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
260
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
261 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
262 """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
263
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
264 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
265
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
266 >>> 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
267 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
268 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
269 >>> 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
270 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
271 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
272 >>>
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 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
275 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
276 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
277 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
278
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
279 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
280 """
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 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
283 return
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
284 self.b = b
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
285 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
286 self.fullbcount = None
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
287 self.__chain_b()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
288
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
289 # 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
290 # 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
291 # 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
292 # 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
293 # 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
294 # 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
295 # 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
296 # b2j also does not contain entries for "popular" elements, meaning
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
297 # elements that account for more than 1 + 1% of the total elements, and
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
298 # 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
299 # 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
300 # 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
301 # 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
302 # 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
303 # 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
304 # repeatedly
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
305
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
306 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
307 # 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
308 # 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
309 # 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
310 # 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
311 # 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
312 # have guessed that.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
313 # 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
314 # 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
315 # 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
316 # from the start.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
317 b = self.b
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
318 self.b2j = b2j = {}
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
319
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
320 for i, elt in enumerate(b):
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
321 indices = b2j.setdefault(elt, [])
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
322 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
323
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
324 # Purge junk elements
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
325 junk = set()
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
326 isjunk = self.isjunk
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
327 if isjunk:
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
328 for elt in list(b2j.keys()): # using list() since b2j is modified
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
329 if isjunk(elt):
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
330 junk.add(elt)
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
331 del b2j[elt]
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
332
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
333 # Purge popular elements that are not junk
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
334 popular = set()
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
335 n = len(b)
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
336 if self.autojunk and n >= 200:
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
337 ntest = n // 100 + 1
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
338 for elt, idxs in list(b2j.items()):
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
339 if len(idxs) > ntest:
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
340 popular.add(elt)
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
341 del b2j[elt]
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
342
66156
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
343 # Now for x in b, isjunk(x) == x in junk, but the latter is much faster.
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
344 # Sicne the number of *unique* junk elements is probably small, the
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
345 # memory burden of keeping this set alive is likely trivial compared to
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
346 # the size of b2j.
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
347 self.isbjunk = junk.__contains__
1a65290e6d03 #2986 Add autojunk parameter to SequenceMatcher to optionally disable 'popular == junk' heuristic.
Terry Reedy <tjreedy@udel.edu>
parents: 60552
diff changeset
348 self.isbpopular = popular.__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)
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
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)
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
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)
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
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 = []
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
413 for i in xrange(alo, ahi):
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
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
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
38811
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
465 i and in j. New in Python 2.5, it's also guaranteed that if
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
466 (i, j, n) and (i', j', n') are adjacent triples in the list, and
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
467 the second is not the last triple in the list, then i+n != i' or
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
468 j+n != j'. IOW, adjacent triples never describe adjacent equal
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
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")
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
475 >>> s.get_matching_blocks()
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
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
38784
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
diff changeset
483 # This is most naturally expressed as a recursive algorithm, but
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
diff changeset
484 # at least one user bumped into extreme use cases that exceeded
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
diff changeset
485 # the recursion limit on their box. So, now we maintain a list
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
diff changeset
486 # ('queue`) of blocks we still need to look at, and append partial
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
diff changeset
487 # results to `matching_blocks` in a loop; the matches are sorted
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
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)]
38811
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
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()
38784
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
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
38784
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
diff changeset
497 if k: # if k is 0, there was no matching block
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
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))
38784
9b8507cfbe95 get_matching_blocks(): rewrote code & comments so they match; added
Tim Peters <tim.peters@gmail.com>
parents: 38704
diff changeset
503 matching_blocks.sort()
38811
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
504
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
505 # It's possible that we have adjacent equal blocks in the
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
506 # matching_blocks list now. Starting with 2.5, this code was added
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
507 # to collapse them.
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
508 i1 = j1 = k1 = 0
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
509 non_adjacent = []
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
510 for i2, j2, k2 in matching_blocks:
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
511 # Is this block adjacent to i1, j1, k1?
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
512 if i1 + k1 == i2 and j1 + k1 == j2:
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
513 # Yes, so collapse them -- this just increases the length of
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
514 # the first block by the length of the second, and the first
38812
62cf6d58bb53 Repaired typo in new comment.
Tim Peters <tim.peters@gmail.com>
parents: 38811
diff changeset
515 # block so lengthened remains the block to compare against.
38811
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
516 k1 += k2
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
517 else:
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
518 # Not adjacent. Remember the first block (k1==0 means it's
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
519 # the dummy we started with), and make the second block the
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
520 # new block to compare against.
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
521 if k1:
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
522 non_adjacent.append((i1, j1, k1))
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
523 i1, j1, k1 = i2, j2, k2
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
524 if k1:
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
525 non_adjacent.append((i1, j1, k1))
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
526
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
527 non_adjacent.append( (la, lb, 0) )
4558916b841f SequenceMatcher.get_matching_blocks(): This now guarantees that
Tim Peters <tim.peters@gmail.com>
parents: 38784
diff changeset
528 self.matching_blocks = non_adjacent
44633
6b0b5edfb1b7 Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
Raymond Hettinger <python@rcn.com>
parents: 41078
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():
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
551 ... print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
552 ... (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
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
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
593 >>> a = map(str, range(1,40))
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
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
658 matches = reduce(lambda sum, triple: sum + triple[-1],
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
659 self.get_matching_blocks(), 0)
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
660 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
661
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
662 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
663 """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
664
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
665 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
666 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
667 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
668
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
669 # 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
670 # 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
671 # 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
672 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
673 self.fullbcount = fullbcount = {}
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
674 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
675 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
676 fullbcount = self.fullbcount
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
677 # 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
678 # 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
679 avail = {}
47821
0af6f0300eaf Issue 3189: Py3k DeprecationWarning in difflib
Raymond Hettinger <python@rcn.com>
parents: 44633
diff changeset
680 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
681 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
682 if availhas(elt):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
683 numb = avail[elt]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
684 else:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
685 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
686 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
687 if numb > 0:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
688 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
689 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
690
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
691 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
692 """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
693
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
694 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
695 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
696 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
697
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
698 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
699 # 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
700 # shorter sequence
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
701 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
702
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
703 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
704 """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
705
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
706 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
707 string).
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
708
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
709 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
710 (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
711
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
712 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
713 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
714
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
715 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
716 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
717
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
718 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
719 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
720
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
721 >>> 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
722 ['apple', 'ape']
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
723 >>> import keyword as _keyword
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
724 >>> 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
725 ['while']
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
726 >>> 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
727 []
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
728 >>> 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
729 ['except']
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
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
732 if not n > 0:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
diff changeset
733 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
734 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
735 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
736 result = []
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
737 s = SequenceMatcher()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
738 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
739 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
740 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
741 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
742 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
743 s.ratio() >= cutoff:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
744 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
745
30698
3e3fd56ce595 Let library modules use the new keyword arguments for list.sort().
Raymond Hettinger <python@rcn.com>
parents: 29891
diff changeset
746 # 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
747 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
748 # 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
749 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
750
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
751 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
752 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
753 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
754
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
755 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
756
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
757 >>> _count_leading(' abc', ' ')
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
758 3
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
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
761 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
762 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
763 i += 1
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
764 return i
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
765
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
766 class Differ:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
767 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
768 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
769 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
770 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
771 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
772
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
773 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
774
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 1
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
776 '+ ' 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
777 ' ' 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
778 '? ' 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
779
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
780 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
781 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
782 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
783
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
784 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
785 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
786 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
787 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
788 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
789
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
790 Example: Comparing two texts.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
791
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
792 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
793 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
794 `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
795
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
796 >>> 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
797 ... 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
798 ... 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
799 ... 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
800 ... '''.splitlines(1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
801 >>> len(text1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
802 4
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
803 >>> text1[0][-1]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
804 '\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
805 >>> 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
806 ... 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
807 ... 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
808 ... 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
809 ... '''.splitlines(1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
810
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
811 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
812
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
813 >>> d = Differ()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
814
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
815 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
816 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
817
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
818 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
819
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
820 >>> 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
821
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
822 '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
823
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
824 >>> 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
825 >>> _pprint(result)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
826 [' 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
827 '- 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
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 '+ 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
830 '? ++\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
831 '- 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
832 '? ^ ---- ^\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
833 '+ 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
834 '? ++++ ^ ^\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
835 '+ 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
836
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
837 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
838
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
839 >>> print ''.join(result),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
840 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
841 - 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
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 + 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
844 ? ++
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
845 - 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
846 ? ^ ---- ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
847 + 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
848 ? ++++ ^ ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
849 + 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
850
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
851 Methods:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
852
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
853 __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
854 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
855
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
856 compare(a, b)
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
857 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
858 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
859
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
860 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
861 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
862 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
863
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
864 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
865
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
866 - `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
867 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
868 `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
869 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
870 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
871 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
872 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
873 able to craft.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
874
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
875 - `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
876 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
877 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
878 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
879 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
880
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
881 self.linejunk = linejunk
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
882 self.charjunk = charjunk
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
883
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
884 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
885 r"""
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
886 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
887
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
888 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
889 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
890 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
891 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
892 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
893
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
894 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
895
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
896 >>> print ''.join(Differ().compare('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
897 ... 'ore\ntree\nemu\n'.splitlines(1))),
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:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
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."""
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
927 for i in xrange(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)
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
957 >>> print ''.join(results),
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)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
973 for j in xrange(blo, bhi):
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)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
976 for i in xrange(alo, ahi):
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:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
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()
57415
818cd40df865 Merged revisions 76464 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 55049
diff changeset
1063 >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n',
818cd40df865 Merged revisions 76464 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 55049
diff changeset
1064 ... ' ^ ^ ^ ', ' ^ ^ ^ ')
29891
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
1065 >>> for line in results: print repr(line)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1066 ...
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'
57415
818cd40df865 Merged revisions 76464 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 55049
diff changeset
1069 '+ \tabcdefGhijkl\n'
818cd40df865 Merged revisions 76464 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 55049
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], " "))
57415
818cd40df865 Merged revisions 76464 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 55049
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
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1143 ########################################################################
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1144 ### Unified Diff
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1145 ########################################################################
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1146
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1147 def _format_range_unified(start, stop):
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1148 'Convert range to the "ed" format'
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1149 # Per the diff spec at http://www.unix.org/single_unix_specification/
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1150 beginning = start + 1 # lines start numbering with one
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1151 length = stop - start
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1152 if length == 1:
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1153 return '{}'.format(beginning)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1154 if not length:
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1155 beginning -= 1 # empty ranges begin at line just before the range
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1156 return '{},{}'.format(beginning, length)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1157
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1158 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
1159 tofiledate='', n=3, lineterm='\n'):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1160 r"""
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1161 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
1162
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1163 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
1164 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
1165 defaults to three.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1166
29517
94ac1d42a420 Fix docstring
Raymond Hettinger <python@rcn.com>
parents: 29384
diff changeset
1167 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
1168 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
1169 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
1170 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
1171 newlines.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1172
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1173 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
1174 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
1175
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1176 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
1177 times. Any or all of these may be specified using strings for
60552
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1178 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1179 The modification times are normally expressed in the ISO 8601 format.
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1180
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1181 Example:
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 >>> 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
1184 ... 'zero one tree four'.split(), 'Original', 'Current',
60552
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1185 ... '2005-01-26 23:30:50', '2010-04-02 10:20:52',
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1186 ... lineterm=''):
60552
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1187 ... print line # doctest: +NORMALIZE_WHITESPACE
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1188 --- Original 2005-01-26 23:30:50
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1189 +++ Current 2010-04-02 10:20:52
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1190 @@ -1,4 +1,4 @@
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1191 +zero
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1192 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1193 -two
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1194 -three
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1195 +tree
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1196 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1197 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1198
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1199 started = False
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1200 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
1201 if not started:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1202 started = True
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1203 fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1204 todate = '\t{}'.format(tofiledate) if tofiledate else ''
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1205 yield '--- {}{}{}'.format(fromfile, fromdate, lineterm)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1206 yield '+++ {}{}{}'.format(tofile, todate, lineterm)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1207
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1208 first, last = group[0], group[-1]
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1209 file1_range = _format_range_unified(first[1], last[2])
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1210 file2_range = _format_range_unified(first[3], last[4])
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1211 yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1212
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1213 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
1214 if tag == 'equal':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1215 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
1216 yield ' ' + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1217 continue
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1218 if tag in ('replace', 'delete'):
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1219 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
1220 yield '-' + line
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1221 if tag in ('replace', 'insert'):
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1222 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
1223 yield '+' + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1224
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1225
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1226 ########################################################################
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1227 ### Context Diff
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1228 ########################################################################
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1229
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1230 def _format_range_context(start, stop):
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1231 'Convert range to the "ed" format'
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1232 # Per the diff spec at http://www.unix.org/single_unix_specification/
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1233 beginning = start + 1 # lines start numbering with one
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1234 length = stop - start
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1235 if not length:
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1236 beginning -= 1 # empty ranges begin at line just before the range
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1237 if length <= 1:
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1238 return '{}'.format(beginning)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1239 return '{},{}'.format(beginning, beginning + length - 1)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1240
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1241 # 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
1242 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
1243 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
1244 r"""
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1245 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
1246
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1247 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
1248 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
1249 defaults to three.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1250
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1251 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
1252 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
1253 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
1254 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
1255 newlines.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1256
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1257 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
1258 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
1259
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1260 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
1261 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
1262 strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
60552
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1263 The modification times are normally expressed in the ISO 8601 format.
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1264 If not specified, the strings default to blanks.
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1265
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1266 Example:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1267
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1268 >>> print ''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
60552
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1269 ... 'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current')),
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1270 *** Original
713f1f6bf339 Issue #7585: use tab between components in unified and context diff headers.
R. David Murray <rdmurray@bitdance.com>
parents: 57415
diff changeset
1271 --- Current
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1272 ***************
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1273 *** 1,4 ****
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1274 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1275 ! two
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1276 ! three
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1277 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1278 --- 1,4 ----
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1279 + zero
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1280 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1281 ! tree
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1282 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1283 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1284
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1285 prefix = dict(insert='+ ', delete='- ', replace='! ', equal=' ')
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1286 started = False
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1287 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
1288 if not started:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1289 started = True
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1290 fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1291 todate = '\t{}'.format(tofiledate) if tofiledate else ''
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1292 yield '*** {}{}{}'.format(fromfile, fromdate, lineterm)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1293 yield '--- {}{}{}'.format(tofile, todate, lineterm)
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1294
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1295 first, last = group[0], group[-1]
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1296 yield '***************' + lineterm
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1297
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1298 file1_range = _format_range_context(first[1], last[2])
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1299 yield '*** {} ****{}'.format(file1_range, lineterm)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1300
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1301 if any(tag in ('replace', 'delete') for tag, _, _, _, _ in group):
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1302 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
1303 if tag != 'insert':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1304 for line in a[i1:i2]:
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1305 yield prefix[tag] + line
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1306
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1307 file2_range = _format_range_context(first[3], last[4])
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1308 yield '--- {} ----{}'.format(file2_range, lineterm)
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1309
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1310 if any(tag in ('replace', 'insert') for tag, _, _, _, _ in group):
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1311 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
1312 if tag != 'delete':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1313 for line in b[j1:j2]:
69282
09459397f807 Issue 11747: Fix output format for context diffs.
Raymond Hettinger <python@rcn.com>
parents: 68588
diff changeset
1314 yield prefix[tag] + line
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1315
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
1316 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
1317 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1318 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
1319
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1320 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
1321 functions (or None):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1322
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1323 - 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
1324 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
1325 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
1326 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
1327
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1328 - 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
1329 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
1330 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
1331 in this!).
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1332
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1333 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
1334
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1335 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1336
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1337 >>> 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
1338 ... 'ore\ntree\nemu\n'.splitlines(1))
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1339 >>> print ''.join(diff),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1340 - one
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1341 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1342 + ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1343 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1344 - two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1345 - three
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1346 ? -
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1347 + tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1348 + emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1349 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1350 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
1351
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 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
1353 charjunk=IS_CHARACTER_JUNK):
40552
7f76996c7bf4 [Bug #1622533] Make docstrings raw strings because they contain control characters (\0, \1)
Andrew M. Kuchling <amk@amk.ca>
parents: 38812
diff changeset
1354 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
1355
6d3bdd19beeb Patch #914575: difflib 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 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
1357 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
1358 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
1359 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
1360 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
1361 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
1362 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
1363
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
1364 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
1365 (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
1366
6d3bdd19beeb Patch #914575: difflib 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 from/to line tuple -- (line num, line text)
55049
74c0a78114ae Merged revisions 69846 via svnmerge from
Jesus Cea <jcea@jcea.es>
parents: 48205
diff changeset
1368 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
1369 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
1370 '\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
1371 '\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
1372 '\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
1373 '\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
1374
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
1375 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
1376 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
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 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
1379 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
1380 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
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 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
1383 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
1384 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
1385 """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1386 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
1387
6d3bdd19beeb Patch #914575: difflib 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 # 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
1389 change_re = re.compile('(\++|\-+|\^+)')
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1390
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
1391 # 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
1392 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
1393
6d3bdd19beeb Patch #914575: difflib 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 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
1395 """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
1396
6d3bdd19beeb Patch #914575: difflib 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 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
1398 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
1399 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
1400 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
1401 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
1402 '-' 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
1403 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
1404 '?' 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
1405 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
1406 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
1407 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
1408 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
1409 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
1410 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
1411 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
1412
6d3bdd19beeb Patch #914575: difflib 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 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
1414 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
1415 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
1416 """
6d3bdd19beeb Patch #914575: difflib 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 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
1418 # 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
1419 # 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
1420 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
1421 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
1422 # 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
1423 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
1424 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
1425 # 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
1426 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
1427 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
1428 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
1429 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
1430 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
1431 # 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
1432 # 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
1433 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
1434 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
1435 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
1436 # 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
1437 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
1438 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
1439 # 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
1440 # 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
1441 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
1442 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
1443 # 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
1444 text = '\0' + format_key + text + '\1'
35276
4adbd331d335 Fix all wrong instances of "it's".
Georg Brandl <georg@python.org>
parents: 33981
diff changeset
1445 # 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
1446 # 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
1447 # 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
1448 return (num_lines[side],text)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1449
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
1450 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
1451 """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
1452
6d3bdd19beeb Patch #914575: difflib 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 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
1454 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
1455 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
1456 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
1457 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
1458 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
1459
6d3bdd19beeb Patch #914575: difflib 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 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
1461 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
1462 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
1463 """
6d3bdd19beeb Patch #914575: difflib 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 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
1465 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
1466 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
1467 # 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
1468 # 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
1469 # 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
1470 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
1471 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
1472 lines.append(diff_lines_iterator.next())
6d3bdd19beeb Patch #914575: difflib 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 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
1474 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
1475 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
1476 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
1477 # 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
1478 # 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
1479 # 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
1480 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
1481 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
1482 # 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
1483 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
1484 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
1485 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
1486 # 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
1487 # 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
1488 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
1489 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
1490 continue
38704
ba6eebf7c719 Make use of new str.startswith/endswith semantics.
Georg Brandl <georg@python.org>
parents: 36429
diff changeset
1491 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
1492 # 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
1493 # 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
1494 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
1495 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
1496 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
1497 # 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
1498 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
1499 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
1500 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
1501 # 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
1502 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
1503 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
1504 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
1505 # 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
1506 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
1507 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
1508 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
1509 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
1510 # 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
1511 # 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
1512 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
1513 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
1514 continue
38704
ba6eebf7c719 Make use of new str.startswith/endswith semantics.
Georg Brandl <georg@python.org>
parents: 36429
diff changeset
1515 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
1516 # 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
1517 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
1518 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
1519 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
1520 # 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
1521 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
1522 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
1523 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
1524 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
1525 # 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
1526 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
1527 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
1528 # 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
1529 # 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
1530 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
1531 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
1532 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
1533 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
1534 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
1535 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
1536 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
1537 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
1538 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
1539 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
1540
6d3bdd19beeb Patch #914575: difflib 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 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
1542 """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
1543
6d3bdd19beeb Patch #914575: difflib 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 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
1545 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
1546 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
1547 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
1548 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
1549
6d3bdd19beeb Patch #914575: difflib 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 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
1551 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
1552 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
1553 """
6d3bdd19beeb Patch #914575: difflib 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 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
1555 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
1556 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
1557 # 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
1558 while (len(fromlines)==0 or len(tolines)==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
1559 from_line, to_line, found_diff =line_iterator.next()
6d3bdd19beeb Patch #914575: difflib 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 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
1561 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
1562 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
1563 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
1564 # 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
1565 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
1566 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
1567 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
1568
6d3bdd19beeb Patch #914575: difflib 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 # 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
1570 # 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
1571 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
1572 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
1573 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
1574 yield line_pair_iterator.next()
6d3bdd19beeb Patch #914575: difflib 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 # 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
1576 # 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
1577 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
1578 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
1579 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
1580 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
1581 # 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
1582 # 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
1583 # 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
1584 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
1585 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
1586 while(found_diff is 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
1587 from_line, to_line, found_diff = line_pair_iterator.next()
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1588 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
1589 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
1590 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
1591 # 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
1592 # 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
1593 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
1594 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
1595 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
1596 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
1597 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
1598 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
1599 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
1600 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
1601 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
1602 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
1603 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
1604 # 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
1605 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
1606 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
1607 from_line, to_line, found_diff = line_pair_iterator.next()
6d3bdd19beeb Patch #914575: difflib 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 # 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
1609 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
1610 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
1611 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
1612 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
1613 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
1614
6d3bdd19beeb Patch #914575: difflib 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
6d3bdd19beeb Patch #914575: difflib 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 _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
1617 <!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
1618 "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
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 <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
1621
6d3bdd19beeb Patch #914575: difflib 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 <head>
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1623 <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
1624 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
1625 <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
1626 <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
1627 </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
1628 </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
1629
6d3bdd19beeb Patch #914575: difflib 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 <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
1631 %(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
1632 </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
1633
6d3bdd19beeb Patch #914575: difflib 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 </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
1635
6d3bdd19beeb Patch #914575: difflib 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 _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
1637 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
1638 .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
1639 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
1640 .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
1641 .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
1642 .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
1643 .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
1644
6d3bdd19beeb Patch #914575: difflib 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 _table_template = """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1646 <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
1647 cellspacing="0" cellpadding="0" rules="groups" >
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1648 <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
1649 <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
1650 %(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
1651 <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
1652 %(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
1653 </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
1654
6d3bdd19beeb Patch #914575: difflib 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 _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
1656 <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
1657 <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
1658 <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
1659 <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
1660 <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
1661 <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
1662 <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
1663 </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
1664 <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
1665 <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
1666 <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
1667 <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
1668 <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
1669 </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
1670 </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
1671
6d3bdd19beeb Patch #914575: difflib 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 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
1673 """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
1674
6d3bdd19beeb Patch #914575: difflib 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 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
1676 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
1677 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
1678 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
1679
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
1680 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
1681
6d3bdd19beeb Patch #914575: difflib 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 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
1683 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
1684
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1685 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
1686 """
6d3bdd19beeb Patch #914575: difflib 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
6d3bdd19beeb Patch #914575: difflib 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 _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
1689 _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
1690 _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
1691 _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
1692 _default_prefix = 0
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 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
1695 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
1696 """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
1697
6d3bdd19beeb Patch #914575: difflib 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 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
1699 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
1700 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
1701 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
1702 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
1703 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
1704 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
1705 """
6d3bdd19beeb Patch #914575: difflib 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 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
1707 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
1708 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
1709 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
1710
6d3bdd19beeb Patch #914575: difflib 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 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
1712 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
1713 """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
1714
6d3bdd19beeb Patch #914575: difflib 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 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
1716 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
1717 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
1718 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
1719 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
1720 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
1721 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
1722 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
1723 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
1724 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
1725 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
1726 "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
1727 """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1728
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
1729 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
1730 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
1731 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
1732 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
1733 context=context,numlines=numlines))
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1734
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
1735 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
1736 """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
1737
6d3bdd19beeb Patch #914575: difflib 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 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
1739 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
1740 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
1741 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
1742 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
1743 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
1744 """
6d3bdd19beeb Patch #914575: difflib 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 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
1746 # 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
1747 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
1748 # 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
1749 line = line.expandtabs(self._tabsize)
68588
cd8d3c2d3bce #11565: Fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 66156
diff changeset
1750 # replace spaces from expanded tabs back into tab characters
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
1751 # (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
1752 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
1753 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
1754 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
1755 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
1756 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
1757
6d3bdd19beeb Patch #914575: difflib 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 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
1759 """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
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 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
1762 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
1763 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
1764 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
1765 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
1766 """
6d3bdd19beeb Patch #914575: difflib 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 # 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
1768 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
1769 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
1770 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
1771
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1772 # 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
1773 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
1774 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
1775 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
1776 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
1777 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
1778
6d3bdd19beeb Patch #914575: difflib 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 # 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
1780 # 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
1781 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
1782 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
1783 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
1784 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
1785 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
1786 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
1787 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
1788 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
1789 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
1790 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
1791 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
1792 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
1793 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
1794 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
1795
6d3bdd19beeb Patch #914575: difflib 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 # 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
1797 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
1798 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
1799
6d3bdd19beeb Patch #914575: difflib 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 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
1801 # 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
1802 # 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
1803 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
1804 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
1805 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
1806
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1807 # 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
1808 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
1809
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1810 # 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
1811 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
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 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
1814 """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
1815
6d3bdd19beeb Patch #914575: difflib 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 # 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
1817 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
1818 # 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
1819 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
1820 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
1821 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
1822 (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
1823 # 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
1824 # 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
1825 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
1826 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
1827 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
1828 # 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
1829 # 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
1830 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
1831 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
1832 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
1833 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
1834 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
1835 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
1836 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
1837 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
1838 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
1839 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
1840
6d3bdd19beeb Patch #914575: difflib 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 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
1842 """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
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 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
1845 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
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
6d3bdd19beeb Patch #914575: difflib 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 fromlist,tolist,flaglist = [],[],[]
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1849 # 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
1850 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
1851 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
1852 # 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
1853 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
1854 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
1855 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
1856 # 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
1857 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
1858 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
1859 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
1860 return fromlist,tolist,flaglist
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1861
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
1862 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
1863 """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
1864
6d3bdd19beeb Patch #914575: difflib 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 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
1866 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
1867 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
1868 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
1869 """
6d3bdd19beeb Patch #914575: difflib 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 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
1871 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
1872 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
1873 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
1874 # 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
1875 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
1876 # 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
1877 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
1878
6d3bdd19beeb Patch #914575: difflib 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 # 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
1880 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
1881
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1882 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
1883 % (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
1884
6d3bdd19beeb Patch #914575: difflib 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 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
1886 """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
1887
6d3bdd19beeb Patch #914575: difflib 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 # 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
1889 # 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
1890 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
1891 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
1892 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
1893 # 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
1894 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
1895
6d3bdd19beeb Patch #914575: difflib 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 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
1897 """Makes list of "next" links"""
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1898
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
1899 # 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
1900 toprefix = self._prefix[1]
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1901
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
1902 # 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
1903 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
1904 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
1905 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
1906 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
1907 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
1908 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
1909 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
1910 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
1911 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
1912 # 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
1913 # (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
1914 # 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
1915 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
1916 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
1917 # 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
1918 # 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
1919 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
1920 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
1921 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
1922 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
1923 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
1924 # 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
1925 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
1926 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
1927 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
1928 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
1929 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
1930 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
1931 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
1932 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
1933 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
1934 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
1935 # 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
1936 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
1937 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
1938 # 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
1939 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
1940
6d3bdd19beeb Patch #914575: difflib 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 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
1942
6d3bdd19beeb Patch #914575: difflib 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 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
1944 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
1945 """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
1946
6d3bdd19beeb Patch #914575: difflib 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 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
1948 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
1949 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
1950 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
1951 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
1952 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
1953 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
1954 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
1955 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
1956 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
1957 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
1958 "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
1959 """
6d3bdd19beeb Patch #914575: difflib 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
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1961 # 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
1962 # 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
1963 self._make_prefix()
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1964
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
1965 # 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
1966 # 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
1967 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
1968
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
1969 # 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
1970 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
1971 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
1972 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
1973 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
1974 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
1975 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
1976
6d3bdd19beeb Patch #914575: difflib 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 # 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
1978 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
1979 diffs = self._line_wrapper(diffs)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1980
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
1981 # 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
1982 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
1983
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1984 # 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
1985 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
1986 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
1987
41078
f2ba812f7200 SF #1637850: make_table in difflib did not work with unicode
Raymond Hettinger <python@rcn.com>
parents: 40552
diff changeset
1988 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
1989 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
1990 '<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
1991 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
1992 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
1993 # 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
1994 # 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
1995 if i > 0:
41078
f2ba812f7200 SF #1637850: make_table in difflib did not work with unicode
Raymond Hettinger <python@rcn.com>
parents: 40552
diff changeset
1996 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
1997 else:
41078
f2ba812f7200 SF #1637850: make_table in difflib did not work with unicode
Raymond Hettinger <python@rcn.com>
parents: 40552
diff changeset
1998 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
1999 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
2000 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
2001 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
2002 '<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
2003 '<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
2004 '<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
2005 '<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
2006 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
2007 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
2008
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
2009 table = self._table_template % dict(
41078
f2ba812f7200 SF #1637850: make_table in difflib did not work with unicode
Raymond Hettinger <python@rcn.com>
parents: 40552
diff changeset
2010 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
2011 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
2012 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
2013
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
2014 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
2015 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
2016 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
2017 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
2018 replace('\t','&nbsp;')
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
2019
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
2020 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
2021
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2022 def restore(delta, which):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2023 r"""
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
2024 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
2025
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2026 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
2027 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
2028 prefixes.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2029
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2030 Examples:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2031
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2032 >>> 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
2033 ... '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
2034 >>> diff = list(diff)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2035 >>> print ''.join(restore(diff, 1)),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2036 one
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2037 two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2038 three
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2039 >>> print ''.join(restore(diff, 2)),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2040 ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2041 tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2042 emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2043 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2044 try:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2045 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
2046 except KeyError:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2047 raise ValueError, ('unknown delta choice (must be 1 or 2): %r'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2048 % which)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2049 prefixes = (" ", tag)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2050 for line in delta:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2051 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
2052 yield line[2:]
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2053
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2054 def _test():
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2055 import doctest, difflib
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2056 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
2057
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2058 if __name__ == "__main__":
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2059 _test()