third_party/stdlib/difflib.py
def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
                 tofiledate='', n=3, lineterm='\n'):
    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 ---, +++, or @@) are
    created with a trailing newline.  This is helpful so that inputs
    created from file.readlines() result in diffs that are suitable for
    file.writelines() since both the inputs and outputs have trailing
    newlines.

    For inputs that do not have trailing newlines, set the lineterm
    argument to "" so that the output will be uniformly newline free.

    The unidiff format normally has a header for filenames and modification
    times.  Any or all of these may be specified using strings for
    'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
    The modification times are normally expressed in the ISO 8601 format.

    Example:

    >>> for line in unified_diff('one two three four'.split(),
    ...             'zero one tree four'.split(), 'Original', 'Current',
    ...             '2005-01-26 23:30:50', '2010-04-02 10:20:52',
    ...             lineterm=''):
    ...     print line                  # doctest: +NORMALIZE_WHITESPACE
    --- Original        2005-01-26 23:30:50
    +++ Current         2010-04-02 10:20:52
    @@ -1,4 +1,4 @@
    +zero
     one
    -two
    -three
    +tree
     four
    """

    started = False
    for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
        if not started:
            started = True
            # fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
            fromdate = '\t%s' % (fromfiledate) if fromfiledate else ''
            # todate = '\t{}'.format(tofiledate) if tofiledate else ''
            todate = '\t%s' % (tofiledate) if tofiledate else ''
            # yield '--- {}{}{}'.format(fromfile, fromdate, lineterm)
            yield '--- %s%s%s' % (fromfile, fromdate, lineterm)
            # yield '+++ {}{}{}'.format(tofile, todate, lineterm)
            yield '+++ %s%s%s' % (tofile, todate, lineterm)

        first, last = group[0], group[-1]
        file1_range = _format_range_unified(first[1], last[2])
        file2_range = _format_range_unified(first[3], last[4])
        # yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
        yield '@@ -%s +%s @@%s' % (file1_range, file2_range, lineterm)

        for tag, i1, i2, j1, j2 in group:
            if tag == 'equal':
                for line in a[i1:i2]:
                    yield ' ' + line
                continue
            if tag in ('replace', 'delete'):
                for line in a[i1:i2]:
                    yield '-' + line
            if tag in ('replace', 'insert'):
                for line in b[j1:j2]:
                    yield '+' + line
def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
                 tofiledate='', n=3, lineterm='\n'):
    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 ---, +++, or @@) are
    created with a trailing newline.  This is helpful so that inputs
    created from file.readlines() result in diffs that are suitable for
    file.writelines() since both the inputs and outputs have trailing
    newlines.

    For inputs that do not have trailing newlines, set the lineterm
    argument to "" so that the output will be uniformly newline free.

    The unidiff format normally has a header for filenames and modification
    times.  Any or all of these may be specified using strings for
    'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
    The modification times are normally expressed in the ISO 8601 format.

    Example:

    >>> for line in unified_diff('one two three four'.split(),
    ...             'zero one tree four'.split(), 'Original', 'Current',
    ...             '2005-01-26 23:30:50', '2010-04-02 10:20:52',
    ...             lineterm=''):
    ...     print line                  # doctest: +NORMALIZE_WHITESPACE
    --- Original        2005-01-26 23:30:50
    +++ Current         2010-04-02 10:20:52
    @@ -1,4 +1,4 @@
    +zero
     one
    -two
    -three
    +tree
     four
    """

    started = False
    for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
        if not started:
            started = True
            # fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
            fromdate = '\t%s' % (fromfiledate) if fromfiledate else ''
            # todate = '\t{}'.format(tofiledate) if tofiledate else ''
            todate = '\t%s' % (tofiledate) if tofiledate else ''
            # yield '--- {}{}{}'.format(fromfile, fromdate, lineterm)
            yield '--- %s%s%s' % (fromfile, fromdate, lineterm)
            # yield '+++ {}{}{}'.format(tofile, todate, lineterm)
            yield '+++ %s%s%s' % (tofile, todate, lineterm)

        first, last = group[0], group[-1]
        file1_range = _format_range_unified(first[1], last[2])
        file2_range = _format_range_unified(first[3], last[4])
        # yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
        yield '@@ -%s +%s @@%s' % (file1_range, file2_range, lineterm)

        for tag, i1, i2, j1, j2 in group:
            if tag == 'equal':
                for line in a[i1:i2]:
                    yield ' ' + line
                continue
            if tag in ('replace', 'delete'):
                for line in a[i1:i2]:
                    yield '-' + line
            if tag in ('replace', 'insert'):
                for line in b[j1:j2]:
                    yield '+' + line
def unified_diff ( a , b , fromfile = '' , tofile = '' , fromfiledate = '' , tofiledate = '' , n = 3 , lineterm = '\n' ) : started = False for group in SequenceMatcher ( None , a , b ) . get_grouped_opcodes ( n ) : if not started : started = True # fromdate = '\t{}'.format(fromfiledate) if fromfiledate else '' fromdate = '\t%s' % ( fromfiledate ) if fromfiledate else '' # todate = '\t{}'.format(tofiledate) if tofiledate else '' todate = '\t%s' % ( tofiledate ) if tofiledate else '' # yield '--- {}{}{}'.format(fromfile, fromdate, lineterm) yield '--- %s%s%s' % ( fromfile , fromdate , lineterm ) # yield '+++ {}{}{}'.format(tofile, todate, lineterm) yield '+++ %s%s%s' % ( tofile , todate , lineterm ) first , last = group [ 0 ] , group [ - 1 ] file1_range = _format_range_unified ( first [ 1 ] , last [ 2 ] ) file2_range = _format_range_unified ( first [ 3 ] , last [ 4 ] ) # yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm) yield '@@ -%s +%s @@%s' % ( file1_range , file2_range , lineterm ) for tag , i1 , i2 , j1 , j2 in group : if tag == 'equal' : for line in a [ i1 : i2 ] : yield ' ' + line continue if tag in ( 'replace' , 'delete' ) : for line in a [ i1 : i2 ] : yield '-' + line if tag in ( 'replace' , 'insert' ) : for line in b [ j1 : j2 ] : yield '+' + line
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 ---, +++, or @@) are
    created with a trailing newline.  This is helpful so that inputs
    created from file.readlines() result in diffs that are suitable for
    file.writelines() since both the inputs and outputs have trailing
    newlines.

    For inputs that do not have trailing newlines, set the lineterm
    argument to "" so that the output will be uniformly newline free.

    The unidiff format normally has a header for filenames and modification
    times.  Any or all of these may be specified using strings for
    'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
    The modification times are normally expressed in the ISO 8601 format.

    Example:

    >>> for line in unified_diff('one two three four'.split(),
    ...             'zero one tree four'.split(), 'Original', 'Current',
    ...             '2005-01-26 23:30:50', '2010-04-02 10:20:52',
    ...             lineterm=''):
    ...     print line                  # doctest: +NORMALIZE_WHITESPACE
    --- Original        2005-01-26 23:30:50
    +++ Current         2010-04-02 10:20:52
    @@ -1,4 +1,4 @@
    +zero
     one
    -two
    -three
    +tree
     four
r Compare two sequences of lines ; generate the delta as a unified diff .