diff options
author | Victor Stinner <vstinner@python.org> | 2022-10-07 17:57:48 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-07 17:57:48 (GMT) |
commit | 002252c4ade6a5aeb7a397776dbe3c1de0740e84 (patch) | |
tree | 550b94103dfcdef8932141fcfed964b8c59d2ae7 /Doc/includes | |
parent | 24a4b341586be12569e3804b5f1356e745d1f55f (diff) | |
download | cpython-002252c4ade6a5aeb7a397776dbe3c1de0740e84.zip cpython-002252c4ade6a5aeb7a397776dbe3c1de0740e84.tar.gz cpython-002252c4ade6a5aeb7a397776dbe3c1de0740e84.tar.bz2 |
gh-97669: Move difflib examples to Doc/includes/ (#97964)
Remove diff.py and ndiff.py scripts of Tools/scripts/: move them to
Doc/includes/.
* diff.py and ndiff.py files are no longer executable. Remove also
their shebang ("#!/usr/bin/env python3").
* Remove the -profile command from ndiff.py to simply the code.
* Remove ndiff.py copyright and history command. The Python
documentation examples are distributed under the "Zero Clause BSD
License".
Diffstat (limited to 'Doc/includes')
-rw-r--r-- | Doc/includes/diff.py | 59 | ||||
-rw-r--r-- | Doc/includes/ndiff.py | 111 |
2 files changed, 170 insertions, 0 deletions
diff --git a/Doc/includes/diff.py b/Doc/includes/diff.py new file mode 100644 index 0000000..001619f --- /dev/null +++ b/Doc/includes/diff.py @@ -0,0 +1,59 @@ +""" Command line interface to difflib.py providing diffs in four formats: + +* ndiff: lists every line and highlights interline changes. +* context: highlights clusters of changes in a before/after format. +* unified: highlights clusters of changes in an inline format. +* html: generates side by side comparison with change highlights. + +""" + +import sys, os, difflib, argparse +from datetime import datetime, timezone + +def file_mtime(path): + t = datetime.fromtimestamp(os.stat(path).st_mtime, + timezone.utc) + return t.astimezone().isoformat() + +def main(): + + parser = argparse.ArgumentParser() + parser.add_argument('-c', action='store_true', default=False, + help='Produce a context format diff (default)') + parser.add_argument('-u', action='store_true', default=False, + help='Produce a unified format diff') + parser.add_argument('-m', action='store_true', default=False, + help='Produce HTML side by side diff ' + '(can use -c and -l in conjunction)') + parser.add_argument('-n', action='store_true', default=False, + help='Produce a ndiff format diff') + parser.add_argument('-l', '--lines', type=int, default=3, + help='Set number of context lines (default 3)') + parser.add_argument('fromfile') + parser.add_argument('tofile') + options = parser.parse_args() + + n = options.lines + fromfile = options.fromfile + tofile = options.tofile + + fromdate = file_mtime(fromfile) + todate = file_mtime(tofile) + with open(fromfile) as ff: + fromlines = ff.readlines() + with open(tofile) as tf: + tolines = tf.readlines() + + if options.u: + diff = difflib.unified_diff(fromlines, tolines, fromfile, tofile, fromdate, todate, n=n) + elif options.n: + diff = difflib.ndiff(fromlines, tolines) + elif options.m: + diff = difflib.HtmlDiff().make_file(fromlines,tolines,fromfile,tofile,context=options.c,numlines=n) + else: + diff = difflib.context_diff(fromlines, tolines, fromfile, tofile, fromdate, todate, n=n) + + sys.stdout.writelines(diff) + +if __name__ == '__main__': + main() diff --git a/Doc/includes/ndiff.py b/Doc/includes/ndiff.py new file mode 100644 index 0000000..32c251b --- /dev/null +++ b/Doc/includes/ndiff.py @@ -0,0 +1,111 @@ +"""ndiff [-q] file1 file2 + or +ndiff (-r1 | -r2) < ndiff_output > file1_or_file2 + +Print a human-friendly file difference report to stdout. Both inter- +and intra-line differences are noted. In the second form, recreate file1 +(-r1) or file2 (-r2) on stdout, from an ndiff report on stdin. + +In the first form, if -q ("quiet") is not specified, the first two lines +of output are + +-: file1 ++: file2 + +Each remaining line begins with a two-letter code: + + "- " line unique to file1 + "+ " line unique to file2 + " " line common to both files + "? " line not present in either input file + +Lines beginning with "? " attempt to guide the eye to intraline +differences, and were not present in either input file. These lines can be +confusing if the source files contain tab characters. + +The first file can be recovered by retaining only lines that begin with +" " or "- ", and deleting those 2-character prefixes; use ndiff with -r1. + +The second file can be recovered similarly, but by retaining only " " and +"+ " lines; use ndiff with -r2; or, on Unix, the second file can be +recovered by piping the output through + + sed -n '/^[+ ] /s/^..//p' +""" + +__version__ = 1, 7, 0 + +import difflib, sys + +def fail(msg): + out = sys.stderr.write + out(msg + "\n\n") + out(__doc__) + return 0 + +# open a file & return the file object; gripe and return 0 if it +# couldn't be opened +def fopen(fname): + try: + return open(fname) + except IOError as detail: + return fail("couldn't open " + fname + ": " + str(detail)) + +# open two files & spray the diff to stdout; return false iff a problem +def fcompare(f1name, f2name): + f1 = fopen(f1name) + f2 = fopen(f2name) + if not f1 or not f2: + return 0 + + a = f1.readlines(); f1.close() + b = f2.readlines(); f2.close() + for line in difflib.ndiff(a, b): + print(line, end=' ') + + return 1 + +# crack args (sys.argv[1:] is normal) & compare; +# return false iff a problem + +def main(args): + import getopt + try: + opts, args = getopt.getopt(args, "qr:") + except getopt.error as detail: + return fail(str(detail)) + noisy = 1 + qseen = rseen = 0 + for opt, val in opts: + if opt == "-q": + qseen = 1 + noisy = 0 + elif opt == "-r": + rseen = 1 + whichfile = val + if qseen and rseen: + return fail("can't specify both -q and -r") + if rseen: + if args: + return fail("no args allowed with -r option") + if whichfile in ("1", "2"): + restore(whichfile) + return 1 + return fail("-r value must be 1 or 2") + if len(args) != 2: + return fail("need 2 filename args") + f1name, f2name = args + if noisy: + print('-:', f1name) + print('+:', f2name) + return fcompare(f1name, f2name) + +# read ndiff output from stdin, and print file1 (which=='1') or +# file2 (which=='2') to stdout + +def restore(which): + restored = difflib.restore(sys.stdin.readlines(), which) + sys.stdout.writelines(restored) + +if __name__ == '__main__': + main(sys.argv[1:]) |