annotate Lib/difflib.py @ 40582:67287ca4e1e8

Merged revisions 53005-53303 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r53012 | walter.doerwald | 2006-12-12 22:55:31 +0100 (Tue, 12 Dec 2006) | 2 lines Fix typo. ........ r53023 | brett.cannon | 2006-12-13 23:31:37 +0100 (Wed, 13 Dec 2006) | 2 lines Remove an unneeded import of 'warnings'. ........ r53025 | brett.cannon | 2006-12-14 00:02:38 +0100 (Thu, 14 Dec 2006) | 2 lines Remove unneeded imports of 'warnings'. ........ r53026 | brett.cannon | 2006-12-14 00:09:53 +0100 (Thu, 14 Dec 2006) | 4 lines Add test.test_support.guard_warnings_filter . This function returns a context manager that protects warnings.filter from being modified once the context is exited. ........ r53029 | george.yoshida | 2006-12-14 03:22:44 +0100 (Thu, 14 Dec 2006) | 2 lines Note that guard_warnings_filter was added in 2.6 ........ r53031 | vinay.sajip | 2006-12-14 09:53:55 +0100 (Thu, 14 Dec 2006) | 1 line Added news on recent changes to logging ........ r53032 | andrew.kuchling | 2006-12-14 19:57:53 +0100 (Thu, 14 Dec 2006) | 1 line [Patch #1599256 from David Watson] check that os.fsync is available before using it ........ r53042 | kurt.kaiser | 2006-12-15 06:13:11 +0100 (Fri, 15 Dec 2006) | 6 lines 1. Avoid hang when encountering a duplicate in a completion list. Bug 1571112. 2. Duplicate some old entries from Python's NEWS to IDLE's NEWS.txt M AutoCompleteWindow.py M NEWS.txt ........ r53048 | andrew.kuchling | 2006-12-18 18:12:31 +0100 (Mon, 18 Dec 2006) | 1 line [Bug #1618083] Add missing word; make a few grammar fixes ........ r53050 | andrew.kuchling | 2006-12-18 18:16:05 +0100 (Mon, 18 Dec 2006) | 1 line Bump version ........ r53051 | andrew.kuchling | 2006-12-18 18:22:07 +0100 (Mon, 18 Dec 2006) | 1 line [Bug #1616726] Fix description of generator.close(); if you raise some random exception, the exception is raised and doesn't trigger a RuntimeError ........ r53052 | andrew.kuchling | 2006-12-18 18:38:14 +0100 (Mon, 18 Dec 2006) | 1 line Describe new methods in Queue module ........ r53053 | andrew.kuchling | 2006-12-18 20:22:24 +0100 (Mon, 18 Dec 2006) | 1 line [Patch #1615868 by Lars Gustaebel] Use Py_off_t to fix BZ2File.seek() for offsets > 2Gb ........ r53057 | andrew.kuchling | 2006-12-18 22:29:07 +0100 (Mon, 18 Dec 2006) | 1 line Fix markup ........ r53063 | thomas.wouters | 2006-12-19 09:17:50 +0100 (Tue, 19 Dec 2006) | 5 lines Make sre's SubPattern objects accept slice objects like it already accepts simple slices. ........ r53065 | andrew.kuchling | 2006-12-19 15:13:05 +0100 (Tue, 19 Dec 2006) | 6 lines [Patch #1618455 by Ben Maurer] Improve speed of HMAC by using str.translate() instead of a more general XOR that has to construct a list. Slightly modified from Maurer's patch: the _strxor() function is no longer necessary at all. ........ r53066 | andrew.kuchling | 2006-12-19 15:28:23 +0100 (Tue, 19 Dec 2006) | 9 lines [Bug #1613651] Document socket.recv_into, socket.recvfrom_into Also, the text for recvfrom told you to read recv() for an explanation of the 'flags' argument, but recv() just pointed you at the man page. Copied the man-page text to recvfrom(), recvfrom_into, recv_into to avoid the pointless redirection. I don't have LaTeX on this machine; hope my markup is OK. ........ r53067 | andrew.kuchling | 2006-12-19 15:29:04 +0100 (Tue, 19 Dec 2006) | 1 line Comment typo ........ r53068 | andrew.kuchling | 2006-12-19 16:11:41 +0100 (Tue, 19 Dec 2006) | 1 line [Patch #1617413 from Dug Song] Fix HTTP Basic authentication via HTTPS ........ r53071 | andrew.kuchling | 2006-12-19 16:18:12 +0100 (Tue, 19 Dec 2006) | 1 line [Patch #1600491 from Jim Jewett] Describe how to build help files on Windows ........ r53073 | andrew.kuchling | 2006-12-19 16:43:10 +0100 (Tue, 19 Dec 2006) | 6 lines [Patch #1587139 by kxroberto] Protect lock acquisition/release with try...finally to ensure the lock is always released. This could use the 'with' statement, but the patch uses 'finally'. 2.5 backport candidate. ........ r53074 | vinay.sajip | 2006-12-19 19:29:11 +0100 (Tue, 19 Dec 2006) | 1 line Updated documentation for findCaller() to indicate that a 3-tuple is now returned, rather than a 2-tuple. ........ r53090 | georg.brandl | 2006-12-19 23:06:46 +0100 (Tue, 19 Dec 2006) | 3 lines Patch #1484695: The tarfile module now raises a HeaderError exception if a buffer given to frombuf() is invalid. ........ r53099 | raymond.hettinger | 2006-12-20 07:42:06 +0100 (Wed, 20 Dec 2006) | 5 lines Bug #1590891: random.randrange don't return correct value for big number Needs to be backported. ........ r53106 | georg.brandl | 2006-12-20 12:55:16 +0100 (Wed, 20 Dec 2006) | 3 lines Testcase for patch #1484695. ........ r53110 | andrew.kuchling | 2006-12-20 20:48:20 +0100 (Wed, 20 Dec 2006) | 17 lines [Apply length-checking.diff from bug #1599254] Add length checking to single-file mailbox formats: before doing a flush() on a mailbox, seek to the end and verify its length is unchanged, raising ExternalClashError if the file's length has changed. This fix avoids potential data loss if some other process appends to the mailbox file after the table of contents has been generated; instead of overwriting the modified file, you'll get the exception. I also noticed that the self._lookup() call in self.flush() wasn't necessary (everything that sets self._pending to True also calls self.lookup()), and replaced it by an assertion. 2.5 backport candidate. ........ r53112 | andrew.kuchling | 2006-12-20 20:57:10 +0100 (Wed, 20 Dec 2006) | 1 line [Bug #1619674] Make sum() use the term iterable, not sequence ........ r53113 | andrew.kuchling | 2006-12-20 20:58:11 +0100 (Wed, 20 Dec 2006) | 1 line Two grammar fixes ........ r53115 | andrew.kuchling | 2006-12-20 21:11:12 +0100 (Wed, 20 Dec 2006) | 5 lines Some other built-in functions are described with 'sequence' arguments that should really be 'iterable'; this commit changes them. Did I miss any? Did I introduce any errors? ........ r53117 | andrew.kuchling | 2006-12-20 21:20:42 +0100 (Wed, 20 Dec 2006) | 1 line [Bug #1619680] in_dll() arguments are documented in the wrong order ........ r53120 | neal.norwitz | 2006-12-21 05:38:00 +0100 (Thu, 21 Dec 2006) | 1 line Lars asked for permission on on python-dev for work on tarfile.py ........ r53125 | andrew.kuchling | 2006-12-21 14:40:29 +0100 (Thu, 21 Dec 2006) | 1 line Mention the os.SEEK_* constants ........ r53129 | walter.doerwald | 2006-12-21 19:06:30 +0100 (Thu, 21 Dec 2006) | 2 lines Fix typo. ........ r53131 | thomas.heller | 2006-12-21 19:30:56 +0100 (Thu, 21 Dec 2006) | 3 lines Fix wrong markup of an argument in a method signature. Will backport. ........ r53137 | andrew.kuchling | 2006-12-22 01:50:56 +0100 (Fri, 22 Dec 2006) | 1 line Typo fix ........ r53139 | andrew.kuchling | 2006-12-22 14:25:02 +0100 (Fri, 22 Dec 2006) | 1 line [Bug #737202; fix from Titus Brown] Make CGIHTTPServer work for scripts in sub-directories ........ r53141 | andrew.kuchling | 2006-12-22 16:04:45 +0100 (Fri, 22 Dec 2006) | 6 lines [Bug #802128] Make the mode argument of dumbdbm actually work the way it's described, and add a test for it. 2.5 bugfix candidate, maybe; arguably this patch changes the API of dumbdbm and shouldn't be added in a point-release. ........ r53142 | andrew.kuchling | 2006-12-22 16:16:58 +0100 (Fri, 22 Dec 2006) | 6 lines [Bug #802128 continued] Modify mode depending on the process umask. Is there really no other way to read the umask than to set it? Hope this works on Windows... ........ r53145 | andrew.kuchling | 2006-12-22 17:43:26 +0100 (Fri, 22 Dec 2006) | 1 line [Bug #776202] Apply Walter Doerwald's patch to use text mode for encoded files ........ r53146 | andrew.kuchling | 2006-12-22 19:41:42 +0100 (Fri, 22 Dec 2006) | 9 lines [Patch #783050 from Patrick Lynch] The emulation of forkpty() is incorrect; the master should close the slave fd. Added a test to test_pty.py that reads from the master_fd after doing a pty.fork(); without the fix it hangs forever instead of raising an exception. (<crossing fingers for the buildbots>) 2.5 backport candidate. ........ r53147 | andrew.kuchling | 2006-12-22 20:06:16 +0100 (Fri, 22 Dec 2006) | 1 line [Patch #827559 from Chris Gonnerman] Make SimpleHTTPServer redirect when a directory URL is missing the trailing slash; this lets relative links work. ........ r53149 | andrew.kuchling | 2006-12-22 20:21:27 +0100 (Fri, 22 Dec 2006) | 1 line Darn; this test works when you run test_pty.py directly, but fails when regrtest runs it (the os.read() raises os.error). I can't figure out the cause, so am commenting out the test. ........ r53150 | andrew.kuchling | 2006-12-22 22:48:19 +0100 (Fri, 22 Dec 2006) | 1 line Frak; this test also fails ........ r53153 | lars.gustaebel | 2006-12-23 17:40:13 +0100 (Sat, 23 Dec 2006) | 5 lines Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell() work correctly together with readline(). Will backport to 2.5. ........ r53155 | lars.gustaebel | 2006-12-23 18:57:23 +0100 (Sat, 23 Dec 2006) | 5 lines Patch #1262036: Prevent TarFiles from being added to themselves under certain conditions. Will backport to 2.5. ........ r53159 | andrew.kuchling | 2006-12-27 04:25:31 +0100 (Wed, 27 Dec 2006) | 4 lines [Part of patch #1182394] Move the HMAC blocksize to be a class-level constant; this allows changing it in a subclass. To accommodate this, copy() now uses __class__. Also add some text to a comment. ........ r53160 | andrew.kuchling | 2006-12-27 04:31:24 +0100 (Wed, 27 Dec 2006) | 1 line [Rest of patch #1182394] Add ._current() method so that we can use the written-in-C .hexdigest() method ........ r53161 | lars.gustaebel | 2006-12-27 11:30:46 +0100 (Wed, 27 Dec 2006) | 4 lines Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument. Will backport to 2.5. ........ r53165 | neal.norwitz | 2006-12-28 05:39:20 +0100 (Thu, 28 Dec 2006) | 1 line Remove a stray (old) macro name left around (I guess) ........ r53188 | neal.norwitz | 2006-12-29 04:01:53 +0100 (Fri, 29 Dec 2006) | 1 line SF bug #1623890, fix argument name in docstring ........ r53200 | raymond.hettinger | 2006-12-30 05:01:17 +0100 (Sat, 30 Dec 2006) | 1 line For sets with cyclical reprs, emit an ellipsis instead of infinitely recursing. ........ r53232 | brett.cannon | 2007-01-04 01:23:49 +0100 (Thu, 04 Jan 2007) | 3 lines Add EnvironmentVarGuard to test.test_support. Provides a context manager to temporarily set or unset environment variables. ........ r53235 | neal.norwitz | 2007-01-04 07:25:31 +0100 (Thu, 04 Jan 2007) | 1 line SF #1627373, fix typo in CarbonEvt. ........ r53244 | raymond.hettinger | 2007-01-04 18:53:34 +0100 (Thu, 04 Jan 2007) | 1 line Fix stability of heapq's nlargest() and nsmallest(). ........ r53249 | martin.v.loewis | 2007-01-04 22:06:12 +0100 (Thu, 04 Jan 2007) | 3 lines Bug #1566280: Explicitly invoke threading._shutdown from Py_Main, to avoid relying on atexit. Will backport to 2.5. ........ r53252 | gregory.p.smith | 2007-01-05 02:59:42 +0100 (Fri, 05 Jan 2007) | 3 lines Support linking of the bsddb module against BerkeleyDB 4.5.x (will backport to 2.5) ........ r53253 | gregory.p.smith | 2007-01-05 03:06:17 +0100 (Fri, 05 Jan 2007) | 2 lines bump module version to match supported berkeleydb version ........ r53255 | neal.norwitz | 2007-01-05 06:25:22 +0100 (Fri, 05 Jan 2007) | 6 lines Prevent crash on shutdown which can occur if we are finalizing and the module dict has been cleared already and some object raises a warning (like in a __del__). Will backport. ........ r53258 | gregory.p.smith | 2007-01-05 08:21:35 +0100 (Fri, 05 Jan 2007) | 2 lines typo fix ........ r53260 | neal.norwitz | 2007-01-05 09:06:43 +0100 (Fri, 05 Jan 2007) | 1 line Add Collin Winter for access to update PEP 3107 ........ r53262 | andrew.kuchling | 2007-01-05 15:22:17 +0100 (Fri, 05 Jan 2007) | 1 line [Bug #1622533] Make docstrings raw strings because they contain control characters (\0, \1) ........ r53264 | andrew.kuchling | 2007-01-05 16:51:24 +0100 (Fri, 05 Jan 2007) | 1 line [Patch #1520904] Fix bsddb tests to write to the temp directory instead of the Lib/bsddb/test directory ........ r53279 | brett.cannon | 2007-01-05 22:45:09 +0100 (Fri, 05 Jan 2007) | 3 lines Silence a warning from gcc 4.0.1 by specifying a function's parameter list is 'void' instead of just a set of empty parentheses. ........ r53285 | raymond.hettinger | 2007-01-06 02:14:41 +0100 (Sat, 06 Jan 2007) | 2 lines SF# 1409443: Expand comment to cover the interaction between f->f_lasti and the PREDICT macros. ........ r53286 | anthony.baxter | 2007-01-06 05:45:54 +0100 (Sat, 06 Jan 2007) | 1 line update to (c) years to include 2007 ........ r53291 | neal.norwitz | 2007-01-06 22:24:35 +0100 (Sat, 06 Jan 2007) | 1 line Add Josiah to SF for maintaining asyncore/asynchat ........ r53293 | peter.astrand | 2007-01-07 09:53:46 +0100 (Sun, 07 Jan 2007) | 1 line Re-implemented fix for #1531862 once again, in a way that works with Python 2.2. Fixes bug #1603424. ........ r53295 | peter.astrand | 2007-01-07 15:34:16 +0100 (Sun, 07 Jan 2007) | 1 line Avoid O(N**2) bottleneck in _communicate_(). Fixes #1598181. ........ r53300 | raymond.hettinger | 2007-01-08 19:09:20 +0100 (Mon, 08 Jan 2007) | 1 line Fix zero-length corner case for iterating over a mutating deque. ........ r53301 | vinay.sajip | 2007-01-08 19:50:32 +0100 (Mon, 08 Jan 2007) | 4 lines Bare except clause removed from SMTPHandler.emit(). Now, only ImportError is trapped. Bare except clause removed from SocketHandler.createSocket(). Now, only socket.error is trapped. (SF #411881) ........ r53302 | vinay.sajip | 2007-01-08 19:51:46 +0100 (Mon, 08 Jan 2007) | 2 lines Bare except clause removed from LogRecord.__init__. Now, only ValueError, TypeError and AttributeError are trapped. (SF #411881) ........ r53303 | vinay.sajip | 2007-01-08 19:52:36 +0100 (Mon, 08 Jan 2007) | 1 line Added entries about removal of some bare except clauses from logging. ........
author Thomas Wouters <thomas@python.org>
date Tue, 09 Jan 2007 23:18:33 +0000
parents e86c0b29b4a2
children 4cdf21a0dbbc
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',
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
33 'unified_diff', 'HtmlDiff']
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
408a40e65247 Apply heapq.nlargest() to find best matches.
Raymond Hettinger <python@rcn.com>
parents: 31515
diff changeset
36
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
37 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
38 if length:
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
39 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
40 return 1.0
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
41
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
42 class SequenceMatcher:
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
43
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
44 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
45 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
46 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
47 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
48 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
49 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
50 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
51 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
52 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
53 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
54 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
55
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
56 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
57 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
58 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
59 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
60 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
61 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
62 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
63 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
64 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
65 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
66 "junk" <wink>.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
67
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
68 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
69
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
70 >>> 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
71 ... "private Thread currentThread;",
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
72 ... "private volatile Thread currentThread;")
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
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
75 .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
76 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
77 sequences are close matches:
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 >>> 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
80 0.866
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
81 >>>
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 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
84 .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
85
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
86 >>> 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
87 ... 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
88 a[0] and b[0] match for 8 elements
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
89 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
90 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
91
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
92 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
93 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
94 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
95
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
96 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
97 use .get_opcodes():
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
98
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
99 >>> 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
100 ... 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
101 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
102 insert a[8:8] b[8:17]
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
103 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
104
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
105 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
106 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
107 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
108
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
109 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
110 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
111
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
112 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
113 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
114 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
115 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
116
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
117 Methods:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
118
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
119 __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
120 Construct a SequenceMatcher.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
121
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
122 set_seqs(a, b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
123 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
124
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
125 set_seq1(a)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
126 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
127
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
128 set_seq2(b)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
129 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
130
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
131 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
132 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
133
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
134 get_matching_blocks()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
135 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
136
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
137 get_opcodes()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
138 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
139
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
140 ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
141 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
142
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
143 quick_ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
144 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
145
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
146 real_quick_ratio()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
147 Return an upper bound on ratio() very quickly.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
148 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
149
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
150 def __init__(self, isjunk=None, a='', b=''):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
151 """Construct a SequenceMatcher.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
152
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
153 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
154 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
155 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
156 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
157 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
158 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
159 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
160
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
161 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
162 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
163 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
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 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
166 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
167 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
168 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
169
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
170 # Members:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
171 # a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
172 # first sequence
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
173 # b
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
174 # 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
175 # 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
176 # b2j
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
177 # 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
178 # 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
179 # fullbcount
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
180 # for x in b, 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
181 # 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
182 # 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
183 # matching_blocks
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
184 # 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
185 # 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
186 # 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
187 # opcodes
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
188 # 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
189 # one of
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
190 # '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
191 # '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
192 # '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
193 # '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
194 # isjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
195 # 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
196 # 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
197 # 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
198 # 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
199 # 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
200 # isbjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
201 # for x in b, isbjunk(x) == isjunk(x) but much faster;
39575
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
202 # 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
203 # 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
204 # isbpopular
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
205 # for x in b, isbpopular(x) is true iff b is reasonably long
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
206 # (at least 200 elements) and x accounts for more than 1% of
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
207 # its elements. DOES NOT WORK for x in a!
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
208
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
209 self.isjunk = isjunk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
210 self.a = self.b = None
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
211 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
212
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
213 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
214 """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
215
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
216 >>> s = SequenceMatcher()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
217 >>> 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
218 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
219 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
220 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
221
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
222 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
223 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
224
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
225 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
226 """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
227
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
228 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
229
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
230 >>> 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
231 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
232 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
233 >>> 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
234 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
235 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
236 >>>
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 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
239 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
240 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
241 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
242
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
243 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
244 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
245
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
246 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
247 return
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
248 self.a = a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
249 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
250
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
251 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
252 """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
253
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
254 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
255
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
256 >>> 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
257 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
258 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
259 >>> 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
260 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
261 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
262 >>>
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 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
265 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
266 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
267 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
268
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
269 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
270 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
271
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
272 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
273 return
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
274 self.b = b
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
275 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
276 self.fullbcount = None
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
277 self.__chain_b()
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 # 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
280 # 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
281 # 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
282 # 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
283 # 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
284 # 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
285 # 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
286 # b2j also does not contain entries for "popular" elements, meaning
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
287 # elements that account for more than 1% of the total elements, and
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
288 # 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
289 # 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
290 # 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
291 # 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
292 # 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
293 # 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
294 # repeatedly
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
295
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
296 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
297 # 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
298 # 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
299 # 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
300 # 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
301 # 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
302 # have guessed that.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
303 # 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
304 # 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
305 # 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
306 # from the start.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
307 b = self.b
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
308 n = len(b)
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
309 self.b2j = b2j = {}
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
310 populardict = {}
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
311 for i, elt in enumerate(b):
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
312 if elt in b2j:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
313 indices = b2j[elt]
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
314 if n >= 200 and len(indices) * 100 > n:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
315 populardict[elt] = 1
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
316 del indices[:]
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
317 else:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
318 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
319 else:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
320 b2j[elt] = [i]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
321
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
322 # Purge leftover indices for popular elements.
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
323 for elt in populardict:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
324 del b2j[elt]
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
325
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
326 # Now b2j.keys() contains elements uniquely, and especially when
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
327 # the sequence is a string, that's usually a good deal smaller
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
328 # than len(string). The difference is the number of isjunk calls
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
329 # saved.
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
330 isjunk = self.isjunk
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
331 junkdict = {}
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
332 if isjunk:
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
333 for d in populardict, b2j:
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
334 for elt in d.keys():
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
335 if isjunk(elt):
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
336 junkdict[elt] = 1
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
337 del d[elt]
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
338
23620
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 23300
diff changeset
339 # Now for x in b, isjunk(x) == x in junkdict, but the
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
340 # latter is much faster. Note too that while there may be a
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
341 # lot of junk in the sequence, the number of *unique* junk
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
342 # elements is probably small. So the memory burden of keeping
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
343 # this dict alive is likely trivial compared to the size of b2j.
39575
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
344 self.isbjunk = junkdict.__contains__
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
345 self.isbpopular = populardict.__contains__
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
346
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
347 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
348 """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
349
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
350 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
351
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
352 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
353 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
354 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
355 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
356 k >= k'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
357 i <= i'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
358 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
359
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
360 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
361 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
362 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
363
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
364 >>> 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
365 >>> s.find_longest_match(0, 5, 0, 9)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
366 (0, 4, 5)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
367
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
368 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
369 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
370 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
371 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
372 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
373 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
374
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
375 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
376 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
377 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
378 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
379
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
380 >>> 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
381 >>> s.find_longest_match(0, 5, 0, 9)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
382 (1, 0, 4)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
383
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
384 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
385
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
386 >>> 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
387 >>> s.find_longest_match(0, 2, 0, 1)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
388 (0, 0, 0)
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
389 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
390
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
391 # 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
392 # E.g.,
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
393 # ab
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
394 # acab
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
395 # 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
396 # 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
397 # 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
398 # 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
399 # "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
400 # 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
401 # 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
402
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
403 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
404 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
405 # 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
406 # 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
407 # 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
408 j2len = {}
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
409 nothing = []
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
410 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
411 # 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
412 # 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
413 j2lenget = j2len.get
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
414 newj2len = {}
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
415 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
416 # 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
417 if j < blo:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
418 continue
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
419 if j >= bhi:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
420 break
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
421 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
422 if k > bestsize:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
423 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
424 j2len = newj2len
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
425
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
426 # 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
427 # "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
428 # 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
429 # 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
430 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
431 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
432 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
433 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
434 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
435 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
436 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
437 bestsize += 1
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
438
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
439 # 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
440 # 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
441 # 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
442 # 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
443 # 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
444 # 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
445 # 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
446 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
447 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
448 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
449 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
450 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
451 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
452 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
453 bestsize = bestsize + 1
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
454
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
455 return besti, bestj, bestsize
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
456
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
457 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
458 """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
459
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
460 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
461 a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
462 i and in j. New in Python 2.5, it's also guaranteed that if
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
463 (i, j, n) and (i', j', n') are adjacent triples in the list, and
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
464 the second is not the last triple in the list, then i+n != i' or
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
465 j+n != j'. IOW, adjacent triples never describe adjacent equal
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
466 blocks.
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
467
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
468 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
469 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
470
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
471 >>> 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
472 >>> s.get_matching_blocks()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
473 [(0, 0, 2), (3, 2, 2), (5, 4, 0)]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
474 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
475
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
476 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
477 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
478 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
479
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
480 # This is most naturally expressed as a recursive algorithm, but
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
481 # at least one user bumped into extreme use cases that exceeded
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
482 # the recursion limit on their box. So, now we maintain a list
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
483 # ('queue`) of blocks we still need to look at, and append partial
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
484 # results to `matching_blocks` in a loop; the matches are sorted
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
485 # at the end.
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
486 queue = [(0, la, 0, lb)]
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
487 matching_blocks = []
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
488 while queue:
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
489 alo, ahi, blo, bhi = queue.pop()
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
490 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
491 # 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
492 # 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
493 # a[i+k:ahi] vs b[j+k:bhi] unknown
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
494 if k: # if k is 0, there was no matching block
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
495 matching_blocks.append(x)
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
496 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
497 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
498 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
499 queue.append((i+k, ahi, j+k, bhi))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
500 matching_blocks.sort()
36429
16bfe9386068 Patch #1413711: Certain patterns of differences were making difflib
Gustavo Niemeyer <gustavo@niemeyer.net>
parents: 35276
diff changeset
501
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
502 # It's possible that we have adjacent equal blocks in the
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
503 # matching_blocks list now. Starting with 2.5, this code was added
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
504 # to collapse them.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
505 i1 = j1 = k1 = 0
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
506 non_adjacent = []
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
507 for i2, j2, k2 in matching_blocks:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
508 # Is this block adjacent to i1, j1, k1?
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
509 if i1 + k1 == i2 and j1 + k1 == j2:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
510 # Yes, so collapse them -- this just increases the length of
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
511 # the first block by the length of the second, and the first
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
512 # block so lengthened remains the block to compare against.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
513 k1 += k2
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
514 else:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
515 # Not adjacent. Remember the first block (k1==0 means it's
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
516 # the dummy we started with), and make the second block the
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
517 # new block to compare against.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
518 if k1:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
519 non_adjacent.append((i1, j1, k1))
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
520 i1, j1, k1 = i2, j2, k2
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
521 if k1:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
522 non_adjacent.append((i1, j1, k1))
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
523
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
524 non_adjacent.append( (la, lb, 0) )
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
525 self.matching_blocks = non_adjacent
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
526 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
527
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
528 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
529 """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
530
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
531 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
532 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
533 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
534
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
535 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
536
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
537 '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
538 '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
539 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
540 '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
541 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
542 '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
543
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
544 >>> a = "qabxcd"
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
545 >>> b = "abycdf"
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
546 >>> 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
547 >>> 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
548 ... 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
549 ... (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
550 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
551 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
552 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
553 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
554 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
555 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
556
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
557 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
558 return self.opcodes
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
559 i = j = 0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
560 self.opcodes = answer = []
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
561 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
562 # 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
563 # 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
564 # 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
565 # 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
566 # 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
567 tag = ''
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
568 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
569 tag = 'replace'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
570 elif i < ai:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
571 tag = 'delete'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
572 elif j < bj:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
573 tag = 'insert'
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
574 if tag:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
575 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
576 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
577 # 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
578 # 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
579 if size:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
580 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
581 return answer
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
582
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
583 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
584 """ 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
585
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
586 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
587 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
588
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
589 >>> from pprint import pprint
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
590 >>> 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
591 >>> b = a[:]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
592 >>> 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
593 >>> 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
594 >>> 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
595 >>> 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
596 >>> 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
597 [[('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
598 [('equal', 16, 19, 17, 20),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
599 ('replace', 19, 20, 20, 21),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
600 ('equal', 20, 22, 21, 23),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
601 ('delete', 22, 27, 23, 23),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
602 ('equal', 27, 30, 23, 26)],
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
603 [('equal', 31, 34, 27, 30),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
604 ('replace', 34, 35, 30, 31),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
605 ('equal', 35, 38, 31, 34)]]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
606 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
607
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
608 codes = self.get_opcodes()
32612
5546c7ae24f7 SequenceMatcher(None, [], []).get_grouped_opcodes() now returns a generator
Brett Cannon <bcannon@gmail.com>
parents: 32357
diff changeset
609 if not codes:
5546c7ae24f7 SequenceMatcher(None, [], []).get_grouped_opcodes() now returns a generator
Brett Cannon <bcannon@gmail.com>
parents: 32357
diff changeset
610 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
611 # 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
612 if codes[0][0] == 'equal':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
613 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
614 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
615 if codes[-1][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[-1]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
617 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
618
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
619 nn = n + n
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
620 group = []
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
621 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
622 # 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
623 # 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
624 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
625 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
626 yield group
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
627 group = []
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
628 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
629 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
630 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
631 yield group
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
632
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
633 def ratio(self):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
634 """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
635
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
636 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
637 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
638 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
639 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
640
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
641 .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
642 .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
643 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
644 upper bound.
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
645
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
646 >>> 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
647 >>> s.ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
648 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
649 >>> s.quick_ratio()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
650 0.75
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
651 >>> 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
652 1.0
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
653 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
654
39627
e86c0b29b4a2 Kill reduce(). A coproduction of John Reese, Jacques Frechet, and Alex M.
Guido van Rossum <guido@python.org>
parents: 39575
diff changeset
655 matches = sum(triple[-1] for triple in self.get_matching_blocks())
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
656 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
657
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
658 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
659 """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
660
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
661 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
662 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
663 """
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 # 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
666 # 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
667 # 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
668 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
669 self.fullbcount = fullbcount = {}
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
670 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
671 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
672 fullbcount = self.fullbcount
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
673 # 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
674 # 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
675 avail = {}
39575
63237fcefd99 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
676 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
677 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
678 if availhas(elt):
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
679 numb = avail[elt]
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
680 else:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
681 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
682 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
683 if numb > 0:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
684 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
685 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
686
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
687 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
688 """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
689
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
690 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
691 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
692 """
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 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
695 # 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
696 # shorter sequence
29719
fa4cf878c538 Fix SF bug #763023, difflib.py: ratio() zero division not caught
Neal Norwitz <nnorwitz@gmail.com>
parents: 29517
diff changeset
697 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
698
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
699 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
700 """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
701
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
702 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
703 string).
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
704
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
705 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
706 (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
707
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
708 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
709 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
710
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
711 Optional arg 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
712 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
713
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
714 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
715 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
716
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
717 >>> 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
718 ['apple', 'ape']
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
719 >>> import keyword as _keyword
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
720 >>> 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
721 ['while']
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
722 >>> 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
723 []
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
724 >>> 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
725 ['except']
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
726 """
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
727
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
728 if not n > 0:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
diff changeset
729 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
730 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
731 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
732 result = []
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
733 s = SequenceMatcher()
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
734 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
735 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
736 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
737 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
738 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
739 s.ratio() >= cutoff:
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
740 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
741
30698
3e3fd56ce595 Let library modules use the new keyword arguments for list.sort().
Raymond Hettinger <python@rcn.com>
parents: 29891
diff changeset
742 # 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
743 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
744 # 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
745 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
746
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
747 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
748 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
749 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
750
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
751 Example:
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 >>> _count_leading(' abc', ' ')
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
754 3
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
755 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
756
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
757 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
758 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
759 i += 1
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
760 return i
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
761
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
762 class Differ:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
763 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
764 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
765 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
766 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
767 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
768
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
769 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
770
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
771 '- ' 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
772 '+ ' 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
773 ' ' 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
774 '? ' 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
775
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
776 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
777 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
778 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
779
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
780 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
781 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
782 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
783 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
784 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
785
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
786 Example: Comparing two texts.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
787
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
788 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
789 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
790 `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
791
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
792 >>> 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
793 ... 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
794 ... 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
795 ... 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
796 ... '''.splitlines(1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
797 >>> len(text1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
798 4
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
799 >>> text1[0][-1]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
800 '\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
801 >>> 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
802 ... 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
803 ... 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
804 ... 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
805 ... '''.splitlines(1)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
806
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
807 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
808
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
809 >>> d = Differ()
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 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
812 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
813
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
814 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
815
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
816 >>> 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
817
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
818 '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
819
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
820 >>> 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
821 >>> _pprint(result)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
822 [' 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
823 '- 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
824 '- 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
825 '+ 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
826 '? ++\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
827 '- 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
828 '? ^ ---- ^\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
829 '+ 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
830 '? ++++ ^ ^\n',
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
831 '+ 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
832
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
833 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
834
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
835 >>> print ''.join(result),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
836 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
837 - 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
838 - 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
839 + 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
840 ? ++
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
841 - 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
842 ? ^ ---- ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
843 + 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
844 ? ++++ ^ ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
845 + 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
846
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
847 Methods:
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 __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
850 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
851
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
852 compare(a, b)
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
853 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
854 """
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 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
857 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
858 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
859
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
860 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
861
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
862 - `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
863 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
864 `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
865 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
866 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
867 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
868 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
869 able to craft.
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
870
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
871 - `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
872 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
873 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
874 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
875 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
876
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
877 self.linejunk = linejunk
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
878 self.charjunk = charjunk
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 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
881 r"""
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
882 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
883
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
884 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
885 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
886 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
887 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
888 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
889
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
890 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
891
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
892 >>> 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
893 ... '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
894 - one
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 + ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
897 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
898 - two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
899 - three
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
900 ? -
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
901 + tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
902 + emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
903 """
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 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
906 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
907 if tag == 'replace':
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
908 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
909 elif tag == 'delete':
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
910 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
911 elif tag == 'insert':
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
912 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
913 elif tag == 'equal':
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 else:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
diff changeset
916 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
917
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
918 for line in g:
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
919 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
920
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
921 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
922 """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
923 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
924 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
925
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
926 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
927 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
928 # 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
929 # 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
930 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
931 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
932 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
933 else:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
934 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
935 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
936
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
937 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
938 for line in g:
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
939 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
940
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
941 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
942 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
943 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
944 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
945 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
946 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
947
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
948 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
949
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
950 >>> d = Differ()
29891
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
951 >>> 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
952 ... ['abcdefGhijkl\n'], 0, 1)
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
953 >>> print ''.join(results),
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
954 - abcDefghiJkl
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
955 ? ^ ^ ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
956 + abcdefGhijkl
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
957 ? ^ ^ ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
958 """
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 # 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
961 # 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
962 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
963 cruncher = SequenceMatcher(self.charjunk)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
964 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
965
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
966 # 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
967 # (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
968 # 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
969 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
970 bj = b[j]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
971 cruncher.set_seq2(bj)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
972 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
973 ai = a[i]
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
974 if ai == bj:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
975 if eqi is None:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
976 eqi, eqj = i, j
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
977 continue
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
978 cruncher.set_seq1(ai)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
979 # 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
980 # 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
981 # 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
982 # 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
983 # 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
984 # 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
985 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
986 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
987 cruncher.ratio() > best_ratio:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
988 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
989 if best_ratio < cutoff:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
990 # 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
991 if eqi is None:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
992 # 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
993 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
994 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
995 return
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
996 # 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
997 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
998 else:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
999 # 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
1000 eqi = None
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1001
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1002 # 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
1003 # identical
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1004
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1005 # 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
1006 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
1007 yield line
19200
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 # 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
1010 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
1011 if eqi is None:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1012 # 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
1013 atags = btags = ""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1014 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
1015 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
1016 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
1017 if tag == 'replace':
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1018 atags += '^' * la
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1019 btags += '^' * lb
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1020 elif tag == 'delete':
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1021 atags += '-' * la
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1022 elif tag == 'insert':
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 == 'equal':
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 btags += ' ' * lb
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1027 else:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30698
diff changeset
1028 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
1029 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
1030 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1031 else:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1032 # 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
1033 yield ' ' + aelt
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1034
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1035 # 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
1036 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
1037 yield line
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 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
1040 g = []
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1041 if alo < ahi:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1042 if blo < bhi:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1043 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
1044 else:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1045 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
1046 elif 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._dump('+', b, blo, bhi)
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1048
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1049 for line in g:
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1050 yield line
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1051
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1052 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
1053 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1054 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
1055
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1056 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1057
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1058 >>> d = Differ()
29891
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
1059 >>> results = d._qformat('\tabcDefghiJkl\n', '\t\tabcdefGhijkl\n',
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
1060 ... ' ^ ^ ^ ', '+ ^ ^ ^ ')
9ca291865f9c Fix faulty doctests. There is no results attribute.
Raymond Hettinger <python@rcn.com>
parents: 29719
diff changeset
1061 >>> 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
1062 ...
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1063 '- \tabcDefghiJkl\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1064 '? \t ^ ^ ^\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1065 '+ \t\tabcdefGhijkl\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1066 '? \t ^ ^ ^\n'
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1067 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1068
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1069 # 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
1070 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
1071 _count_leading(bline, "\t"))
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1072 common = min(common, _count_leading(atags[:common], " "))
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1073 atags = atags[common:].rstrip()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1074 btags = btags[common:].rstrip()
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1075
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1076 yield "- " + aline
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1077 if atags:
20240
5c4261e74478 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 20038
diff changeset
1078 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
1079
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1080 yield "+ " + bline
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1081 if btags:
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1082 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
1083
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1084 # 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
1085 # *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
1086 # before: private Thread currentThread;
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1087 # 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
1088 # 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
1089 # 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
1090 # 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
1091 # 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
1092 # 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
1093 # 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
1094 # 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
1095 # 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
1096 # 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
1097 # 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
1098 # 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
1099 # 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
1100
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1101 import re
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1102
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1103 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
1104 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1105 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
1106
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1107 Examples:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1108
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1109 >>> 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
1110 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1111 >>> 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
1112 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1113 >>> 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
1114 False
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1115 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1116
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1117 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
1118
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1119 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
1120 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1121 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
1122
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1123 Examples:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1124
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1125 >>> 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
1126 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1127 >>> 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
1128 True
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1129 >>> 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
1130 False
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1131 >>> 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
1132 False
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1133 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1134
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1135 return ch in ws
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1136
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1137
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1138 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
1139 tofiledate='', n=3, lineterm='\n'):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1140 r"""
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1141 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
1142
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1143 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
1144 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
1145 defaults to three.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1146
29517
94ac1d42a420 Fix docstring
Raymond Hettinger <python@rcn.com>
parents: 29384
diff changeset
1147 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
1148 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
1149 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
1150 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
1151 newlines.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1152
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1153 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
1154 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
1155
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1156 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
1157 times. Any or all of these may be specified using strings for
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1158 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. The modification
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1159 times are normally expressed in the format returned by time.ctime().
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1160
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1161 Example:
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 >>> 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
1164 ... 'zero one tree four'.split(), 'Original', 'Current',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1165 ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:20:52 2003',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1166 ... lineterm=''):
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1167 ... print line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1168 --- Original Sat Jan 26 23:30:50 1991
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1169 +++ Current Fri Jun 06 10:20:52 2003
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1170 @@ -1,4 +1,4 @@
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1171 +zero
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1172 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1173 -two
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1174 -three
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1175 +tree
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1176 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1177 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1178
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1179 started = False
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1180 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
1181 if not started:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1182 yield '--- %s %s%s' % (fromfile, fromfiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1183 yield '+++ %s %s%s' % (tofile, tofiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1184 started = True
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1185 i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1186 yield "@@ -%d,%d +%d,%d @@%s" % (i1+1, i2-i1, j1+1, j2-j1, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1187 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
1188 if tag == 'equal':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1189 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
1190 yield ' ' + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1191 continue
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1192 if tag == 'replace' or tag == 'delete':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1193 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
1194 yield '-' + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1195 if tag == 'replace' or tag == 'insert':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1196 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
1197 yield '+' + line
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 # 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
1200 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
1201 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
1202 r"""
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1203 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
1204
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1205 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
1206 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
1207 defaults to three.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1208
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1209 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
1210 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
1211 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
1212 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
1213 newlines.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1214
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1215 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
1216 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
1217
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1218 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
1219 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
1220 strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1221 The modification times are normally expressed in the format returned
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1222 by time.ctime(). If not specified, the strings default to blanks.
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1223
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1224 Example:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1225
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1226 >>> print ''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1227 ... 'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current',
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1228 ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:22:46 2003')),
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1229 *** Original Sat Jan 26 23:30:50 1991
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1230 --- Current Fri Jun 06 10:22:46 2003
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1231 ***************
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1232 *** 1,4 ****
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1233 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1234 ! two
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1235 ! three
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1236 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1237 --- 1,4 ----
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1238 + zero
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1239 one
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1240 ! tree
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1241 four
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1242 """
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1243
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1244 started = False
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1245 prefixmap = {'insert':'+ ', 'delete':'- ', 'replace':'! ', 'equal':' '}
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1246 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
1247 if not started:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1248 yield '*** %s %s%s' % (fromfile, fromfiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1249 yield '--- %s %s%s' % (tofile, tofiledate, lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1250 started = True
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1251
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1252 yield '***************%s' % (lineterm,)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1253 if group[-1][2] - group[0][1] >= 2:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1254 yield '*** %d,%d ****%s' % (group[0][1]+1, group[-1][2], lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1255 else:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1256 yield '*** %d ****%s' % (group[-1][2], lineterm)
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1257 visiblechanges = [e for e in group if e[0] in ('replace', 'delete')]
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1258 if visiblechanges:
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1259 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
1260 if tag != 'insert':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1261 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
1262 yield prefixmap[tag] + line
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1263
29381
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1264 if group[-1][4] - group[0][3] >= 2:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1265 yield '--- %d,%d ----%s' % (group[0][3]+1, group[-1][4], lineterm)
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1266 else:
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1267 yield '--- %d ----%s' % (group[-1][4], lineterm)
29384
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1268 visiblechanges = [e for e in group if e[0] in ('replace', 'insert')]
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1269 if visiblechanges:
2d39ec0e55aa For the context and unified diff functions:
Raymond Hettinger <python@rcn.com>
parents: 29381
diff changeset
1270 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
1271 if tag != 'delete':
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1272 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
1273 yield prefixmap[tag] + line
15f1dc5b7ddc Added functions for creating context diffs and unified diffs.
Raymond Hettinger <python@rcn.com>
parents: 25953
diff changeset
1274
23300
b5f6e9f6e7f4 Mostly in SequenceMatcher.{__chain_b, find_longest_match}:
Tim Peters <tim.peters@gmail.com>
parents: 22785
diff changeset
1275 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
1276 r"""
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1277 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
1278
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1279 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
1280 functions (or None):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1281
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1282 - 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
1283 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
1284 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
1285 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
1286
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1287 - 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
1288 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
1289 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
1290 in this!).
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1291
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1292 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
1293
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1294 Example:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1295
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1296 >>> 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
1297 ... '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
1298 >>> print ''.join(diff),
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1299 - one
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1300 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1301 + ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1302 ? ^
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1303 - two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1304 - three
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1305 ? -
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1306 + tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1307 + emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1308 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1309 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
1310
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
1311 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
1312 charjunk=IS_CHARACTER_JUNK):
40582
67287ca4e1e8 Merged revisions 53005-53303 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 39627
diff changeset
1313 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
1314
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1315 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
1316 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
1317 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
1318 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
1319 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
1320 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
1321 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
1322
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
1323 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
1324 (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
1325
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1326 from/to line tuple -- (line num, line 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
1327 line num -- integer or None (to indicate a context seperation)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1328 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
1329 '\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
1330 '\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
1331 '\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
1332 '\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
1333
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1334 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
1335 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
1336
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1337 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
1338 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
1339 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
1340
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1341 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
1342 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
1343 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
1344 """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1345 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
1346
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1347 # 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
1348 change_re = re.compile('(\++|\-+|\^+)')
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1349
33319
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1350 # 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
1351 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
1352
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1353 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
1354 """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
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 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
1357 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
1358 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
1359 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
1360 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
1361 '-' 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
1362 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
1363 '?' 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
1364 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
1365 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
1366 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
1367 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
1368 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
1369 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
1370 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
1371
6d3bdd19beeb Patch #914575: difflib 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 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
1373 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
1374 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
1375 """
6d3bdd19beeb Patch #914575: difflib 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 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
1377 # 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
1378 # 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
1379 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
1380 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
1381 # 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
1382 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
1383 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
1384 # 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
1385 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
1386 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
1387 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
1388 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
1389 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
1390 # 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
1391 # 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
1392 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
1393 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
1394 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
1395 # 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
1396 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
1397 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
1398 # 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
1399 # 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
1400 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
1401 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
1402 # 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
1403 text = '\0' + format_key + text + '\1'
35276
4adbd331d335 Fix all wrong instances of "it's".
Georg Brandl <georg@python.org>
parents: 33981
diff changeset
1404 # 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
1405 # 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
1406 # 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
1407 return (num_lines[side],text)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1408
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
1409 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
1410 """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
1411
6d3bdd19beeb Patch #914575: difflib 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 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
1413 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
1414 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
1415 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
1416 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
1417 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
1418
6d3bdd19beeb Patch #914575: difflib 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 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
1420 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
1421 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
1422 """
6d3bdd19beeb Patch #914575: difflib 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 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
1424 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
1425 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
1426 # 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
1427 # 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
1428 # 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
1429 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
1430 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
1431 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
1432 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
1433 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
1434 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
1435 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
1436 # 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
1437 # 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
1438 # 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
1439 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
1440 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
1441 # 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
1442 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
1443 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
1444 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
1445 # 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
1446 # 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
1447 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
1448 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
1449 continue
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
1450 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
1451 # 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
1452 # 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
1453 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
1454 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
1455 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
1456 # 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
1457 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
1458 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
1459 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
1460 # 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
1461 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
1462 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
1463 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
1464 # 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
1465 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
1466 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
1467 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
1468 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
1469 # 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
1470 # 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
1471 num_blanks_pending += 1
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1472 yield 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
1473 continue
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36429
diff changeset
1474 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
1475 # 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
1476 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
1477 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
1478 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
1479 # 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
1480 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
1481 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
1482 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
1483 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
1484 # 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
1485 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
1486 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
1487 # 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
1488 # 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
1489 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
1490 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
1491 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
1492 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
1493 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
1494 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
1495 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
1496 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
1497 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
1498 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
1499
6d3bdd19beeb Patch #914575: difflib 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 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
1501 """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
1502
6d3bdd19beeb Patch #914575: difflib 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 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
1504 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
1505 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
1506 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
1507 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
1508
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1509 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
1510 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
1511 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
1512 """
6d3bdd19beeb Patch #914575: difflib 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 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
1514 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
1515 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
1516 # 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
1517 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
1518 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
1519 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
1520 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
1521 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
1522 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
1523 # 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
1524 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
1525 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
1526 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
1527
6d3bdd19beeb Patch #914575: difflib 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 # 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
1529 # 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
1530 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
1531 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
1532 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
1533 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
1534 # 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
1535 # 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
1536 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
1537 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
1538 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
1539 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
1540 # 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
1541 # 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
1542 # 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
1543 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
1544 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
1545 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
1546 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
1547 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
1548 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
1549 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
1550 # 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
1551 # 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
1552 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
1553 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
1554 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
1555 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
1556 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
1557 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
1558 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
1559 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
1560 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
1561 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
1562 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
1563 # 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
1564 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
1565 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
1566 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
1567 # 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
1568 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
1569 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
1570 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
1571 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
1572 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
1573
6d3bdd19beeb Patch #914575: difflib 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
6d3bdd19beeb Patch #914575: difflib 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 _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
1576 <!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
1577 "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
1578
6d3bdd19beeb Patch #914575: difflib 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 <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
1580
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1581 <head>
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1582 <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
1583 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
1584 <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
1585 <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
1586 </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
1587 </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
1588
6d3bdd19beeb Patch #914575: difflib 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 <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
1590 %(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
1591 </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
1592
6d3bdd19beeb Patch #914575: difflib 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 </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
1594
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1595 _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
1596 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
1597 .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
1598 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
1599 .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
1600 .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
1601 .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
1602 .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
1603
6d3bdd19beeb Patch #914575: difflib 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 _table_template = """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1605 <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
1606 cellspacing="0" cellpadding="0" rules="groups" >
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1607 <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
1608 <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
1609 %(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
1610 <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
1611 %(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
1612 </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
1613
6d3bdd19beeb Patch #914575: difflib 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 _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
1615 <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
1616 <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
1617 <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
1618 <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
1619 <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
1620 <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
1621 <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
1622 </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
1623 <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
1624 <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
1625 <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
1626 <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
1627 <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
1628 </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
1629 </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
1630
6d3bdd19beeb Patch #914575: difflib 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 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
1632 """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
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 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
1635 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
1636 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
1637 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
1638
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
1639 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
1640
6d3bdd19beeb Patch #914575: difflib 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 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
1642 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
1643
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1644 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
1645 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1646
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1647 _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
1648 _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
1649 _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
1650 _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
1651 _default_prefix = 0
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1652
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
1653 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
1654 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
1655 """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
1656
6d3bdd19beeb Patch #914575: difflib 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 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
1658 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
1659 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
1660 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
1661 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
1662 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
1663 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
1664 """
6d3bdd19beeb Patch #914575: difflib 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 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
1666 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
1667 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
1668 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
1669
6d3bdd19beeb Patch #914575: difflib 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 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
1671 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
1672 """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
1673
6d3bdd19beeb Patch #914575: difflib 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 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
1675 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
1676 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
1677 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
1678 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
1679 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
1680 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
1681 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
1682 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
1683 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
1684 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
1685 "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
1686 """
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1687
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
1688 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
1689 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
1690 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
1691 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
1692 context=context,numlines=numlines))
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 _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
1695 """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
1696
6d3bdd19beeb Patch #914575: difflib 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 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
1698 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
1699 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
1700 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
1701 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
1702 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
1703 """
6d3bdd19beeb Patch #914575: difflib 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 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
1705 # 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
1706 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
1707 # 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
1708 line = line.expandtabs(self._tabsize)
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1709 # relace spaces from expanded tabs back into tab characters
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1710 # (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
1711 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
1712 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
1713 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
1714 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
1715 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
1716
6d3bdd19beeb Patch #914575: difflib 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 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
1718 """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
1719
6d3bdd19beeb Patch #914575: difflib 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 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
1721 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
1722 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
1723 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
1724 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
1725 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1726 # 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
1727 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
1728 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
1729 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
1730
6d3bdd19beeb Patch #914575: difflib 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 # 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
1732 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
1733 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
1734 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
1735 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
1736 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
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 # 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
1739 # 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
1740 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
1741 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
1742 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
1743 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
1744 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
1745 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
1746 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
1747 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
1748 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
1749 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
1750 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
1751 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
1752 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
1753 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
1754
6d3bdd19beeb Patch #914575: difflib 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 # 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
1756 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
1757 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
1758
6d3bdd19beeb Patch #914575: difflib 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 # 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
1760 # 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
1761 # 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
1762 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
1763 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
1764 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
1765
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1766 # 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
1767 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
1768
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1769 # 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
1770 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
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 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
1773 """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
1774
6d3bdd19beeb Patch #914575: difflib 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 # 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
1776 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
1777 # 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
1778 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
1779 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
1780 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
1781 (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
1782 # 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
1783 # 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
1784 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
1785 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
1786 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
1787 # 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
1788 # 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
1789 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
1790 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
1791 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
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 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
1794 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
1795 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
1796 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
1797 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
1798 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
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 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
1801 """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
1802
6d3bdd19beeb Patch #914575: difflib 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 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
1804 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
1805 """
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1806
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1807 fromlist,tolist,flaglist = [],[],[]
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1808 # 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
1809 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
1810 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
1811 # 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
1812 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
1813 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
1814 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
1815 # 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
1816 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
1817 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
1818 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
1819 return fromlist,tolist,flaglist
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1820
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
1821 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
1822 """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
1823
6d3bdd19beeb Patch #914575: difflib 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 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
1825 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
1826 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
1827 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
1828 """
6d3bdd19beeb Patch #914575: difflib 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 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
1830 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
1831 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
1832 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
1833 # 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
1834 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
1835 # 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
1836 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
1837
6d3bdd19beeb Patch #914575: difflib 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 # 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
1839 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
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 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
1842 % (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
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 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
1845 """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
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 # 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
1848 # 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
1849 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
1850 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
1851 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
1852 # 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
1853 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
1854
6d3bdd19beeb Patch #914575: difflib 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 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
1856 """Makes list of "next" links"""
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1857
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
1858 # 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
1859 toprefix = self._prefix[1]
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1860
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
1861 # 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
1862 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
1863 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
1864 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
1865 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
1866 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
1867 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
1868 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
1869 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
1870 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
1871 # 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
1872 # (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
1873 # 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
1874 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
1875 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
1876 # 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
1877 # 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
1878 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
1879 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
1880 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
1881 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
1882 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
1883 # 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
1884 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
1885 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
1886 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
1887 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
1888 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
1889 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
1890 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
1891 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
1892 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
1893 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
1894 # 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
1895 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
1896 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
1897 # 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
1898 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
1899
6d3bdd19beeb Patch #914575: difflib 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 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
1901
6d3bdd19beeb Patch #914575: difflib 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 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
1903 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
1904 """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
1905
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1906 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
1907 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
1908 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
1909 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
1910 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
1911 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
1912 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
1913 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
1914 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
1915 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
1916 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
1917 "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
1918 """
6d3bdd19beeb Patch #914575: difflib 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
6d3bdd19beeb Patch #914575: difflib 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 # 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
1921 # 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
1922 self._make_prefix()
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1923
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
1924 # 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
1925 # 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
1926 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
1927
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
1928 # 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
1929 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
1930 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
1931 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
1932 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
1933 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
1934 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
1935
6d3bdd19beeb Patch #914575: difflib 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 # 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
1937 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
1938 diffs = self._line_wrapper(diffs)
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1939
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
1940 # 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
1941 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
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 # 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
1944 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
1945 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
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 import cStringIO
6d3bdd19beeb Patch #914575: difflib 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 s = cStringIO.StringIO()
6d3bdd19beeb Patch #914575: difflib 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 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
1950 '<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
1951 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
1952 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
1953 # 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
1954 # 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
1955 if 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
1956 s.write(' </tbody> \n <tbody>\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
1957 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
1958 s.write( fmt % (next_id[i],next_href[i],fromlist[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
1959 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
1960 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
1961 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
1962 '<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
1963 '<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
1964 '<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
1965 '<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
1966 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
1967 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
1968
6d3bdd19beeb Patch #914575: difflib 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 table = self._table_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
1970 data_rows=s.getvalue(),
6d3bdd19beeb Patch #914575: difflib 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 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
1972 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
1973
6d3bdd19beeb Patch #914575: difflib side by side diff support, diff.py s/b/s HTML option.
Martin v. Löwis <martin@v.loewis.de>
parents: 32867
diff changeset
1974 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
1975 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
1976 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
1977 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
1978 replace('\t','&nbsp;')
33326
787fff51bf2a Whitespace normalization. test_difflib passes again.
Tim Peters <tim.peters@gmail.com>
parents: 33324
diff changeset
1979
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
1980 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
1981
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1982 def restore(delta, which):
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1983 r"""
20038
8a6f2ee6eaba Make difflib.ndiff() and difflib.Differ.compare() generators. This
Tim Peters <tim.peters@gmail.com>
parents: 19200
diff changeset
1984 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
1985
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1986 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
1987 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
1988 prefixes.
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1989
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1990 Examples:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1991
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1992 >>> 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
1993 ... '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
1994 >>> diff = list(diff)
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1995 >>> 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
1996 one
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1997 two
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1998 three
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
1999 >>> 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
2000 ore
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2001 tree
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2002 emu
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2003 """
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2004 try:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2005 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
2006 except KeyError:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2007 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
2008 % which)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2009 prefixes = (" ", tag)
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2010 for line in delta:
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2011 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
2012 yield line[2:]
19200
50fb4683a461 SF patch #445412 extract ndiff functionality to difflib, from
Tim Peters <tim.peters@gmail.com>
parents: 16703
diff changeset
2013
16551
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2014 def _test():
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2015 import doctest, difflib
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2016 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
2017
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2018 if __name__ == "__main__":
7de5043827f7 Moved SequenceMatcher from ndiff into new std library module difflib.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2019 _test()