r""" Compare two sequences of lines; generate the delta as a context diff. Context 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')
| 1193 | |
| 1194 | # See http://www.unix.org/single_unix_specification/ |
| 1195 | def context_diff(a, b, fromfile='', tofile='', |
| 1196 | fromfiledate='', tofiledate='', n=3, lineterm='\n'): |
| 1197 | r""" |
| 1198 | Compare two sequences of lines; generate the delta as a context diff. |
| 1199 | |
| 1200 | Context diffs are a compact way of showing line changes and a few |
| 1201 | lines of context. The number of context lines is set by 'n' which |
| 1202 | defaults to three. |
| 1203 | |
| 1204 | By default, the diff control lines (those with *** or ---) are |
| 1205 | created with a trailing newline. This is helpful so that inputs |
| 1206 | created from file.readlines() result in diffs that are suitable for |
| 1207 | file.writelines() since both the inputs and outputs have trailing |
| 1208 | newlines. |
| 1209 | |
| 1210 | For inputs that do not have trailing newlines, set the lineterm |
| 1211 | argument to "" so that the output will be uniformly newline free. |
| 1212 | |
| 1213 | The context diff format normally has a header for filenames and |
| 1214 | modification times. Any or all of these may be specified using |
| 1215 | strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. |
| 1216 | The modification times are normally expressed in the ISO 8601 format. |
| 1217 | If not specified, the strings default to blanks. |
| 1218 | |
| 1219 | Example: |
| 1220 | |
| 1221 | >>> print(''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(True), |
| 1222 | ... 'zero\none\ntree\nfour\n'.splitlines(True), 'Original', 'Current')), |
| 1223 | ... end="") |
| 1224 | *** Original |
| 1225 | --- Current |
| 1226 | *************** |
| 1227 | *** 1,4 **** |
| 1228 | one |
| 1229 | ! two |
| 1230 | ! three |
| 1231 | four |
| 1232 | --- 1,4 ---- |
| 1233 | + zero |
| 1234 | one |
| 1235 | ! tree |
| 1236 | four |
| 1237 | """ |
| 1238 | |
| 1239 | _check_types(a, b, fromfile, tofile, fromfiledate, tofiledate, lineterm) |
| 1240 | prefix = dict(insert='+ ', delete='- ', replace='! ', equal=' ') |
| 1241 | started = False |
| 1242 | for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): |
| 1243 | if not started: |
| 1244 | started = True |
| 1245 | fromdate = '\t{}'.format(fromfiledate) if fromfiledate else '' |
| 1246 | todate = '\t{}'.format(tofiledate) if tofiledate else '' |
| 1247 | yield '*** {}{}{}'.format(fromfile, fromdate, lineterm) |
| 1248 | yield '--- {}{}{}'.format(tofile, todate, lineterm) |
| 1249 | |
| 1250 | first, last = group[0], group[-1] |
| 1251 | yield '***************' + lineterm |
| 1252 |
nothing calls this directly
no test coverage detected
searching dependent graphs…