r""" Compare two sequences of lines; generate the delta as a unified diff. Unified diffs are a compact way of showing line changes and a few lines of context. The number of context lines is set by 'n' which defaults to three. By default, the diff control lines (those with ---,
(a, b, fromfile='', tofile='', fromfiledate='',
tofiledate='', n=3, lineterm='\n')
| 1094 | return '{},{}'.format(beginning, length) |
| 1095 | |
| 1096 | def unified_diff(a, b, fromfile='', tofile='', fromfiledate='', |
| 1097 | tofiledate='', n=3, lineterm='\n'): |
| 1098 | r""" |
| 1099 | Compare two sequences of lines; generate the delta as a unified diff. |
| 1100 | |
| 1101 | Unified diffs are a compact way of showing line changes and a few |
| 1102 | lines of context. The number of context lines is set by 'n' which |
| 1103 | defaults to three. |
| 1104 | |
| 1105 | By default, the diff control lines (those with ---, +++, or @@) are |
| 1106 | created with a trailing newline. This is helpful so that inputs |
| 1107 | created from file.readlines() result in diffs that are suitable for |
| 1108 | file.writelines() since both the inputs and outputs have trailing |
| 1109 | newlines. |
| 1110 | |
| 1111 | For inputs that do not have trailing newlines, set the lineterm |
| 1112 | argument to "" so that the output will be uniformly newline free. |
| 1113 | |
| 1114 | The unidiff format normally has a header for filenames and modification |
| 1115 | times. Any or all of these may be specified using strings for |
| 1116 | 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. |
| 1117 | The modification times are normally expressed in the ISO 8601 format. |
| 1118 | |
| 1119 | Example: |
| 1120 | |
| 1121 | >>> for line in unified_diff('one two three four'.split(), |
| 1122 | ... 'zero one tree four'.split(), 'Original', 'Current', |
| 1123 | ... '2005-01-26 23:30:50', '2010-04-02 10:20:52', |
| 1124 | ... lineterm=''): |
| 1125 | ... print(line) # doctest: +NORMALIZE_WHITESPACE |
| 1126 | --- Original 2005-01-26 23:30:50 |
| 1127 | +++ Current 2010-04-02 10:20:52 |
| 1128 | @@ -1,4 +1,4 @@ |
| 1129 | +zero |
| 1130 | one |
| 1131 | -two |
| 1132 | -three |
| 1133 | +tree |
| 1134 | four |
| 1135 | """ |
| 1136 | |
| 1137 | _check_types(a, b, fromfile, tofile, fromfiledate, tofiledate, lineterm) |
| 1138 | started = False |
| 1139 | for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): |
| 1140 | if not started: |
| 1141 | started = True |
| 1142 | fromdate = '\t{}'.format(fromfiledate) if fromfiledate else '' |
| 1143 | todate = '\t{}'.format(tofiledate) if tofiledate else '' |
| 1144 | yield '--- {}{}{}'.format(fromfile, fromdate, lineterm) |
| 1145 | yield '+++ {}{}{}'.format(tofile, todate, lineterm) |
| 1146 | |
| 1147 | first, last = group[0], group[-1] |
| 1148 | file1_range = _format_range_unified(first[1], last[2]) |
| 1149 | file2_range = _format_range_unified(first[3], last[4]) |
| 1150 | yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm) |
| 1151 | |
| 1152 | for tag, i1, i2, j1, j2 in group: |
| 1153 | if tag == 'equal': |
nothing calls this directly
no test coverage detected