r""" Differ is a class for comparing sequences of lines of text, and producing human-readable differences or deltas. Differ uses SequenceMatcher both to compare sequences of lines, and to compare sequences of characters within similar (near-matching) lines. Each line of a
| 722 | |
| 723 | |
| 724 | class Differ: |
| 725 | r""" |
| 726 | Differ is a class for comparing sequences of lines of text, and |
| 727 | producing human-readable differences or deltas. Differ uses |
| 728 | SequenceMatcher both to compare sequences of lines, and to compare |
| 729 | sequences of characters within similar (near-matching) lines. |
| 730 | |
| 731 | Each line of a Differ delta begins with a two-letter code: |
| 732 | |
| 733 | '- ' line unique to sequence 1 |
| 734 | '+ ' line unique to sequence 2 |
| 735 | ' ' line common to both sequences |
| 736 | '? ' line not present in either input sequence |
| 737 | |
| 738 | Lines beginning with '? ' attempt to guide the eye to intraline |
| 739 | differences, and were not present in either input sequence. These lines |
| 740 | can be confusing if the sequences contain tab characters. |
| 741 | |
| 742 | Note that Differ makes no claim to produce a *minimal* diff. To the |
| 743 | contrary, minimal diffs are often counter-intuitive, because they synch |
| 744 | up anywhere possible, sometimes accidental matches 100 pages apart. |
| 745 | Restricting synch points to contiguous matches preserves some notion of |
| 746 | locality, at the occasional cost of producing a longer diff. |
| 747 | |
| 748 | Example: Comparing two texts. |
| 749 | |
| 750 | First we set up the texts, sequences of individual single-line strings |
| 751 | ending with newlines (such sequences can also be obtained from the |
| 752 | `readlines()` method of file-like objects): |
| 753 | |
| 754 | >>> text1 = ''' 1. Beautiful is better than ugly. |
| 755 | ... 2. Explicit is better than implicit. |
| 756 | ... 3. Simple is better than complex. |
| 757 | ... 4. Complex is better than complicated. |
| 758 | ... '''.splitlines(keepends=True) |
| 759 | >>> len(text1) |
| 760 | 4 |
| 761 | >>> text1[0][-1] |
| 762 | '\n' |
| 763 | >>> text2 = ''' 1. Beautiful is better than ugly. |
| 764 | ... 3. Simple is better than complex. |
| 765 | ... 4. Complicated is better than complex. |
| 766 | ... 5. Flat is better than nested. |
| 767 | ... '''.splitlines(keepends=True) |
| 768 | |
| 769 | Next we instantiate a Differ object: |
| 770 | |
| 771 | >>> d = Differ() |
| 772 | |
| 773 | Note that when instantiating a Differ object we may pass functions to |
| 774 | filter out line and character 'junk'. See Differ.__init__ for details. |
| 775 | |
| 776 | Finally, we compare the two: |
| 777 | |
| 778 | >>> result = list(d.compare(text1, text2)) |
| 779 | |
| 780 | 'result' is a list of strings, so let's pretty-print it: |
| 781 |