Back to index

python3.2  3.2.2
Classes | Functions | Variables
difflib Namespace Reference

Classes

class  SequenceMatcher
class  Differ
class  HtmlDiff

Functions

def _calculate_ratio
def get_close_matches
def _count_leading
def IS_LINE_JUNK
def IS_CHARACTER_JUNK
def _format_range_unified
 Unified Diff.
def unified_diff
def _format_range_context
 Context Diff.
def context_diff
def ndiff
def _mdiff
def restore
def _test

Variables

list __all__
tuple Match = _namedtuple('Match', 'a b size')
string _file_template
string _styles
string _table_template
string _legend

Function Documentation

def difflib._calculate_ratio (   matches,
  length 
) [private]

Definition at line 41 of file difflib.py.

00041 
00042 def _calculate_ratio(matches, length):
00043     if length:
00044         return 2.0 * matches / length
00045     return 1.0

Here is the caller graph for this function:

def difflib._count_leading (   line,
  ch 
) [private]
Return number of `ch` characters at the start of `line`.

Example:

>>> _count_leading('   abc', ' ')
3

Definition at line 754 of file difflib.py.

00754 
00755 def _count_leading(line, ch):
00756     """
00757     Return number of `ch` characters at the start of `line`.
00758 
00759     Example:
00760 
00761     >>> _count_leading('   abc', ' ')
00762     3
00763     """
00764 
00765     i, n = 0, len(line)
00766     while i < n and line[i] == ch:
00767         i += 1
00768     return i

Here is the caller graph for this function:

def difflib._format_range_context (   start,
  stop 
) [private]

Context Diff.

Definition at line 1234 of file difflib.py.

01234 
01235 def _format_range_context(start, stop):
01236     'Convert range to the "ed" format'
01237     # Per the diff spec at http://www.unix.org/single_unix_specification/
01238     beginning = start + 1     # lines start numbering with one
01239     length = stop - start
01240     if not length:
01241         beginning -= 1        # empty ranges begin at line just before the range
01242     if length <= 1:
01243         return '{}'.format(beginning)
01244     return '{},{}'.format(beginning, beginning + length - 1)
01245 
# See http://www.unix.org/single_unix_specification/

Here is the call graph for this function:

Here is the caller graph for this function:

def difflib._format_range_unified (   start,
  stop 
) [private]

Unified Diff.

Definition at line 1151 of file difflib.py.

01151 
01152 def _format_range_unified(start, stop):
01153     'Convert range to the "ed" format'
01154     # Per the diff spec at http://www.unix.org/single_unix_specification/
01155     beginning = start + 1     # lines start numbering with one
01156     length = stop - start
01157     if length == 1:
01158         return '{}'.format(beginning)
01159     if not length:
01160         beginning -= 1        # empty ranges begin at line just before the range
01161     return '{},{}'.format(beginning, length)

Here is the call graph for this function:

Here is the caller graph for this function:

def difflib._mdiff (   fromlines,
  tolines,
  context = None,
  linejunk = None,
  charjunk = IS_CHARACTER_JUNK 
) [private]

Definition at line 1358 of file difflib.py.

01358 
01359            charjunk=IS_CHARACTER_JUNK):
01360     r"""Returns generator yielding marked up from/to side by side differences.
01361 
01362     Arguments:
01363     fromlines -- list of text lines to compared to tolines
01364     tolines -- list of text lines to be compared to fromlines
01365     context -- number of context lines to display on each side of difference,
01366                if None, all from/to text lines will be generated.
01367     linejunk -- passed on to ndiff (see ndiff documentation)
01368     charjunk -- passed on to ndiff (see ndiff documentation)
01369 
01370     This function returns an interator which returns a tuple:
01371     (from line tuple, to line tuple, boolean flag)
01372 
01373     from/to line tuple -- (line num, line text)
01374         line num -- integer or None (to indicate a context separation)
01375         line text -- original line text with following markers inserted:
01376             '\0+' -- marks start of added text
01377             '\0-' -- marks start of deleted text
01378             '\0^' -- marks start of changed text
01379             '\1' -- marks end of added/deleted/changed text
01380 
01381     boolean flag -- None indicates context separation, True indicates
01382         either "from" or "to" line contains a change, otherwise False.
01383 
01384     This function/iterator was originally developed to generate side by side
01385     file difference for making HTML pages (see HtmlDiff class for example
01386     usage).
01387 
01388     Note, this function utilizes the ndiff function to generate the side by
01389     side difference markup.  Optional ndiff arguments may be passed to this
01390     function and they in turn will be passed to ndiff.
01391     """
01392     import re
01393 
01394     # regular expression for finding intraline change indices
01395     change_re = re.compile('(\++|\-+|\^+)')
01396 
01397     # create the difference iterator to generate the differences
01398     diff_lines_iterator = ndiff(fromlines,tolines,linejunk,charjunk)
01399 
01400     def _make_line(lines, format_key, side, num_lines=[0,0]):
01401         """Returns line of text with user's change markup and line formatting.
01402 
01403         lines -- list of lines from the ndiff generator to produce a line of
01404                  text from.  When producing the line of text to return, the
01405                  lines used are removed from this list.
01406         format_key -- '+' return first line in list with "add" markup around
01407                           the entire line.
01408                       '-' return first line in list with "delete" markup around
01409                           the entire line.
01410                       '?' return first line in list with add/delete/change
01411                           intraline markup (indices obtained from second line)
01412                       None return first line in list with no markup
01413         side -- indice into the num_lines list (0=from,1=to)
01414         num_lines -- from/to current line number.  This is NOT intended to be a
01415                      passed parameter.  It is present as a keyword argument to
01416                      maintain memory of the current line numbers between calls
01417                      of this function.
01418 
01419         Note, this function is purposefully not defined at the module scope so
01420         that data it needs from its parent function (within whose context it
01421         is defined) does not need to be of module scope.
01422         """
01423         num_lines[side] += 1
01424         # Handle case where no user markup is to be added, just return line of
01425         # text with user's line format to allow for usage of the line number.
01426         if format_key is None:
01427             return (num_lines[side],lines.pop(0)[2:])
01428         # Handle case of intraline changes
01429         if format_key == '?':
01430             text, markers = lines.pop(0), lines.pop(0)
01431             # find intraline changes (store change type and indices in tuples)
01432             sub_info = []
01433             def record_sub_info(match_object,sub_info=sub_info):
01434                 sub_info.append([match_object.group(1)[0],match_object.span()])
01435                 return match_object.group(1)
01436             change_re.sub(record_sub_info,markers)
01437             # process each tuple inserting our special marks that won't be
01438             # noticed by an xml/html escaper.
01439             for key,(begin,end) in sub_info[::-1]:
01440                 text = text[0:begin]+'\0'+key+text[begin:end]+'\1'+text[end:]
01441             text = text[2:]
01442         # Handle case of add/delete entire line
01443         else:
01444             text = lines.pop(0)[2:]
01445             # if line of text is just a newline, insert a space so there is
01446             # something for the user to highlight and see.
01447             if not text:
01448                 text = ' '
01449             # insert marks that won't be noticed by an xml/html escaper.
01450             text = '\0' + format_key + text + '\1'
01451         # Return line of text, first allow user's line formatter to do its
01452         # thing (such as adding the line number) then replace the special
01453         # marks with what the user's change markup.
01454         return (num_lines[side],text)
01455 
01456     def _line_iterator():
01457         """Yields from/to lines of text with a change indication.
01458 
01459         This function is an iterator.  It itself pulls lines from a
01460         differencing iterator, processes them and yields them.  When it can
01461         it yields both a "from" and a "to" line, otherwise it will yield one
01462         or the other.  In addition to yielding the lines of from/to text, a
01463         boolean flag is yielded to indicate if the text line(s) have
01464         differences in them.
01465 
01466         Note, this function is purposefully not defined at the module scope so
01467         that data it needs from its parent function (within whose context it
01468         is defined) does not need to be of module scope.
01469         """
01470         lines = []
01471         num_blanks_pending, num_blanks_to_yield = 0, 0
01472         while True:
01473             # Load up next 4 lines so we can look ahead, create strings which
01474             # are a concatenation of the first character of each of the 4 lines
01475             # so we can do some very readable comparisons.
01476             while len(lines) < 4:
01477                 try:
01478                     lines.append(next(diff_lines_iterator))
01479                 except StopIteration:
01480                     lines.append('X')
01481             s = ''.join([line[0] for line in lines])
01482             if s.startswith('X'):
01483                 # When no more lines, pump out any remaining blank lines so the
01484                 # corresponding add/delete lines get a matching blank line so
01485                 # all line pairs get yielded at the next level.
01486                 num_blanks_to_yield = num_blanks_pending
01487             elif s.startswith('-?+?'):
01488                 # simple intraline change
01489                 yield _make_line(lines,'?',0), _make_line(lines,'?',1), True
01490                 continue
01491             elif s.startswith('--++'):
01492                 # in delete block, add block coming: we do NOT want to get
01493                 # caught up on blank lines yet, just process the delete line
01494                 num_blanks_pending -= 1
01495                 yield _make_line(lines,'-',0), None, True
01496                 continue
01497             elif s.startswith(('--?+', '--+', '- ')):
01498                 # in delete block and see a intraline change or unchanged line
01499                 # coming: yield the delete line and then blanks
01500                 from_line,to_line = _make_line(lines,'-',0), None
01501                 num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0
01502             elif s.startswith('-+?'):
01503                 # intraline change
01504                 yield _make_line(lines,None,0), _make_line(lines,'?',1), True
01505                 continue
01506             elif s.startswith('-?+'):
01507                 # intraline change
01508                 yield _make_line(lines,'?',0), _make_line(lines,None,1), True
01509                 continue
01510             elif s.startswith('-'):
01511                 # delete FROM line
01512                 num_blanks_pending -= 1
01513                 yield _make_line(lines,'-',0), None, True
01514                 continue
01515             elif s.startswith('+--'):
01516                 # in add block, delete block coming: we do NOT want to get
01517                 # caught up on blank lines yet, just process the add line
01518                 num_blanks_pending += 1
01519                 yield None, _make_line(lines,'+',1), True
01520                 continue
01521             elif s.startswith(('+ ', '+-')):
01522                 # will be leaving an add block: yield blanks then add line
01523                 from_line, to_line = None, _make_line(lines,'+',1)
01524                 num_blanks_to_yield,num_blanks_pending = num_blanks_pending+1,0
01525             elif s.startswith('+'):
01526                 # inside an add block, yield the add line
01527                 num_blanks_pending += 1
01528                 yield None, _make_line(lines,'+',1), True
01529                 continue
01530             elif s.startswith(' '):
01531                 # unchanged text, yield it to both sides
01532                 yield _make_line(lines[:],None,0),_make_line(lines,None,1),False
01533                 continue
01534             # Catch up on the blank lines so when we yield the next from/to
01535             # pair, they are lined up.
01536             while(num_blanks_to_yield < 0):
01537                 num_blanks_to_yield += 1
01538                 yield None,('','\n'),True
01539             while(num_blanks_to_yield > 0):
01540                 num_blanks_to_yield -= 1
01541                 yield ('','\n'),None,True
01542             if s.startswith('X'):
01543                 raise StopIteration
01544             else:
01545                 yield from_line,to_line,True
01546 
01547     def _line_pair_iterator():
01548         """Yields from/to lines of text with a change indication.
01549 
01550         This function is an iterator.  It itself pulls lines from the line
01551         iterator.  Its difference from that iterator is that this function
01552         always yields a pair of from/to text lines (with the change
01553         indication).  If necessary it will collect single from/to lines
01554         until it has a matching pair from/to pair to yield.
01555 
01556         Note, this function is purposefully not defined at the module scope so
01557         that data it needs from its parent function (within whose context it
01558         is defined) does not need to be of module scope.
01559         """
01560         line_iterator = _line_iterator()
01561         fromlines,tolines=[],[]
01562         while True:
01563             # Collecting lines of text until we have a from/to pair
01564             while (len(fromlines)==0 or len(tolines)==0):
01565                 from_line, to_line, found_diff = next(line_iterator)
01566                 if from_line is not None:
01567                     fromlines.append((from_line,found_diff))
01568                 if to_line is not None:
01569                     tolines.append((to_line,found_diff))
01570             # Once we have a pair, remove them from the collection and yield it
01571             from_line, fromDiff = fromlines.pop(0)
01572             to_line, to_diff = tolines.pop(0)
01573             yield (from_line,to_line,fromDiff or to_diff)
01574 
01575     # Handle case where user does not want context differencing, just yield
01576     # them up without doing anything else with them.
01577     line_pair_iterator = _line_pair_iterator()
01578     if context is None:
01579         while True:
01580             yield next(line_pair_iterator)
01581     # Handle case where user wants context differencing.  We must do some
01582     # storage of lines until we know for sure that they are to be yielded.
01583     else:
01584         context += 1
01585         lines_to_write = 0
01586         while True:
01587             # Store lines up until we find a difference, note use of a
01588             # circular queue because we only need to keep around what
01589             # we need for context.
01590             index, contextLines = 0, [None]*(context)
01591             found_diff = False
01592             while(found_diff is False):
01593                 from_line, to_line, found_diff = next(line_pair_iterator)
01594                 i = index % context
01595                 contextLines[i] = (from_line, to_line, found_diff)
01596                 index += 1
01597             # Yield lines that we have collected so far, but first yield
01598             # the user's separator.
01599             if index > context:
01600                 yield None, None, None
01601                 lines_to_write = context
01602             else:
01603                 lines_to_write = index
01604                 index = 0
01605             while(lines_to_write):
01606                 i = index % context
01607                 index += 1
01608                 yield contextLines[i]
01609                 lines_to_write -= 1
01610             # Now yield the context lines after the change
01611             lines_to_write = context-1
01612             while(lines_to_write):
01613                 from_line, to_line, found_diff = next(line_pair_iterator)
01614                 # If another change within the context, extend the context
01615                 if found_diff:
01616                     lines_to_write = context-1
01617                 else:
01618                     lines_to_write -= 1
01619                 yield from_line, to_line, found_diff
01620 

Here is the call graph for this function:

Here is the caller graph for this function:

def difflib._test ( ) [private]

Definition at line 2059 of file difflib.py.

02059 
02060 def _test():
02061     import doctest, difflib
02062     return doctest.testmod(difflib)

Here is the call graph for this function:

def difflib.context_diff (   a,
  b,
  fromfile = '',
  tofile = '',
  fromfiledate = '',
  tofiledate = '',
  n = 3,
  lineterm = '\n' 
)

Definition at line 1247 of file difflib.py.

01247 
01248                  fromfiledate='', tofiledate='', n=3, lineterm='\n'):
01249     r"""
01250     Compare two sequences of lines; generate the delta as a context diff.
01251 
01252     Context diffs are a compact way of showing line changes and a few
01253     lines of context.  The number of context lines is set by 'n' which
01254     defaults to three.
01255 
01256     By default, the diff control lines (those with *** or ---) are
01257     created with a trailing newline.  This is helpful so that inputs
01258     created from file.readlines() result in diffs that are suitable for
01259     file.writelines() since both the inputs and outputs have trailing
01260     newlines.
01261 
01262     For inputs that do not have trailing newlines, set the lineterm
01263     argument to "" so that the output will be uniformly newline free.
01264 
01265     The context diff format normally has a header for filenames and
01266     modification times.  Any or all of these may be specified using
01267     strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
01268     The modification times are normally expressed in the ISO 8601 format.
01269     If not specified, the strings default to blanks.
01270 
01271     Example:
01272 
01273     >>> print(''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
01274     ...       'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current')),
01275     ...       end="")
01276     *** Original
01277     --- Current
01278     ***************
01279     *** 1,4 ****
01280       one
01281     ! two
01282     ! three
01283       four
01284     --- 1,4 ----
01285     + zero
01286       one
01287     ! tree
01288       four
01289     """
01290 
01291     prefix = dict(insert='+ ', delete='- ', replace='! ', equal='  ')
01292     started = False
01293     for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
01294         if not started:
01295             started = True
01296             fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
01297             todate = '\t{}'.format(tofiledate) if tofiledate else ''
01298             yield '*** {}{}{}'.format(fromfile, fromdate, lineterm)
01299             yield '--- {}{}{}'.format(tofile, todate, lineterm)
01300 
01301         first, last = group[0], group[-1]
01302         yield '***************' + lineterm
01303 
01304         file1_range = _format_range_context(first[1], last[2])
01305         yield '*** {} ****{}'.format(file1_range, lineterm)
01306 
01307         if any(tag in {'replace', 'delete'} for tag, _, _, _, _ in group):
01308             for tag, i1, i2, _, _ in group:
01309                 if tag != 'insert':
01310                     for line in a[i1:i2]:
01311                         yield prefix[tag] + line
01312 
01313         file2_range = _format_range_context(first[3], last[4])
01314         yield '--- {} ----{}'.format(file2_range, lineterm)
01315 
01316         if any(tag in {'replace', 'insert'} for tag, _, _, _, _ in group):
01317             for tag, _, _, j1, j2 in group:
01318                 if tag != 'delete':
01319                     for line in b[j1:j2]:
01320                         yield prefix[tag] + line

Here is the call graph for this function:

Here is the caller graph for this function:

def difflib.get_close_matches (   word,
  possibilities,
  n = 3,
  cutoff = 0.6 
)
Use SequenceMatcher to return list of the best "good enough" matches.

word is a sequence for which close matches are desired (typically a
string).

possibilities is a list of sequences against which to match word
(typically a list of strings).

Optional arg n (default 3) is the maximum number of close matches to
return.  n must be > 0.

Optional arg cutoff (default 0.6) is a float in [0, 1].  Possibilities
that don't score at least that similar to word are ignored.

The best (no more than n) matches among the possibilities are returned
in a list, sorted by similarity score, most similar first.

>>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"])
['apple', 'ape']
>>> import keyword as _keyword
>>> get_close_matches("wheel", _keyword.kwlist)
['while']
>>> get_close_matches("Apple", _keyword.kwlist)
[]
>>> get_close_matches("accept", _keyword.kwlist)
['except']

Definition at line 706 of file difflib.py.

00706 
00707 def get_close_matches(word, possibilities, n=3, cutoff=0.6):
00708     """Use SequenceMatcher to return list of the best "good enough" matches.
00709 
00710     word is a sequence for which close matches are desired (typically a
00711     string).
00712 
00713     possibilities is a list of sequences against which to match word
00714     (typically a list of strings).
00715 
00716     Optional arg n (default 3) is the maximum number of close matches to
00717     return.  n must be > 0.
00718 
00719     Optional arg cutoff (default 0.6) is a float in [0, 1].  Possibilities
00720     that don't score at least that similar to word are ignored.
00721 
00722     The best (no more than n) matches among the possibilities are returned
00723     in a list, sorted by similarity score, most similar first.
00724 
00725     >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"])
00726     ['apple', 'ape']
00727     >>> import keyword as _keyword
00728     >>> get_close_matches("wheel", _keyword.kwlist)
00729     ['while']
00730     >>> get_close_matches("Apple", _keyword.kwlist)
00731     []
00732     >>> get_close_matches("accept", _keyword.kwlist)
00733     ['except']
00734     """
00735 
00736     if not n >  0:
00737         raise ValueError("n must be > 0: %r" % (n,))
00738     if not 0.0 <= cutoff <= 1.0:
00739         raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,))
00740     result = []
00741     s = SequenceMatcher()
00742     s.set_seq2(word)
00743     for x in possibilities:
00744         s.set_seq1(x)
00745         if s.real_quick_ratio() >= cutoff and \
00746            s.quick_ratio() >= cutoff and \
00747            s.ratio() >= cutoff:
00748             result.append((s.ratio(), x))
00749 
00750     # Move the best scorers to head of list
00751     result = heapq.nlargest(n, result)
00752     # Strip scores for the best n matches
00753     return [x for score, x in result]

Here is the call graph for this function:

def difflib.IS_CHARACTER_JUNK (   ch,
  ws = " \t" 
)

Definition at line 1128 of file difflib.py.

01128 
01129 def IS_CHARACTER_JUNK(ch, ws=" \t"):
01130     r"""
01131     Return 1 for ignorable character: iff `ch` is a space or tab.
01132 
01133     Examples:
01134 
01135     >>> IS_CHARACTER_JUNK(' ')
01136     True
01137     >>> IS_CHARACTER_JUNK('\t')
01138     True
01139     >>> IS_CHARACTER_JUNK('\n')
01140     False
01141     >>> IS_CHARACTER_JUNK('x')
01142     False
01143     """
01144 
01145     return ch in ws
01146 

def difflib.IS_LINE_JUNK (   line,
  pat = re.compile(r"\s*#?\s*$").match 
)

Definition at line 1112 of file difflib.py.

01112 
01113 def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match):
01114     r"""
01115     Return 1 for ignorable line: iff `line` is blank or contains a single '#'.
01116 
01117     Examples:
01118 
01119     >>> IS_LINE_JUNK('\n')
01120     True
01121     >>> IS_LINE_JUNK('  #   \n')
01122     True
01123     >>> IS_LINE_JUNK('hello\n')
01124     False
01125     """
01126 
01127     return pat(line) is not None

def difflib.ndiff (   a,
  b,
  linejunk = None,
  charjunk = IS_CHARACTER_JUNK 
)

Definition at line 1321 of file difflib.py.

01321 
01322 def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK):
01323     r"""
01324     Compare `a` and `b` (lists of strings); return a `Differ`-style delta.
01325 
01326     Optional keyword parameters `linejunk` and `charjunk` are for filter
01327     functions (or None):
01328 
01329     - linejunk: A function that should accept a single string argument, and
01330       return true iff the string is junk.  The default is None, and is
01331       recommended; as of Python 2.3, an adaptive notion of "noise" lines is
01332       used that does a good job on its own.
01333 
01334     - charjunk: A function that should accept a string of length 1. The
01335       default is module-level function IS_CHARACTER_JUNK, which filters out
01336       whitespace characters (a blank or tab; note: bad idea to include newline
01337       in this!).
01338 
01339     Tools/scripts/ndiff.py is a command-line front-end to this function.
01340 
01341     Example:
01342 
01343     >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
01344     ...              'ore\ntree\nemu\n'.splitlines(1))
01345     >>> print(''.join(diff), end="")
01346     - one
01347     ?  ^
01348     + ore
01349     ?  ^
01350     - two
01351     - three
01352     ?  -
01353     + tree
01354     + emu
01355     """
01356     return Differ(linejunk, charjunk).compare(a, b)

Here is the call graph for this function:

Here is the caller graph for this function:

def difflib.restore (   delta,
  which 
)

Definition at line 2027 of file difflib.py.

02027 
02028 def restore(delta, which):
02029     r"""
02030     Generate one of the two sequences that generated a delta.
02031 
02032     Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract
02033     lines originating from file 1 or 2 (parameter `which`), stripping off line
02034     prefixes.
02035 
02036     Examples:
02037 
02038     >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
02039     ...              'ore\ntree\nemu\n'.splitlines(1))
02040     >>> diff = list(diff)
02041     >>> print(''.join(restore(diff, 1)), end="")
02042     one
02043     two
02044     three
02045     >>> print(''.join(restore(diff, 2)), end="")
02046     ore
02047     tree
02048     emu
02049     """
02050     try:
02051         tag = {1: "- ", 2: "+ "}[int(which)]
02052     except KeyError:
02053         raise ValueError('unknown delta choice (must be 1 or 2): %r'
02054                            % which)
02055     prefixes = ("  ", tag)
02056     for line in delta:
02057         if line[:2] in prefixes:
02058             yield line[2:]

Here is the caller graph for this function:

def difflib.unified_diff (   a,
  b,
  fromfile = '',
  tofile = '',
  fromfiledate = '',
  tofiledate = '',
  n = 3,
  lineterm = '\n' 
)

Definition at line 1163 of file difflib.py.

01163 
01164                  tofiledate='', n=3, lineterm='\n'):
01165     r"""
01166     Compare two sequences of lines; generate the delta as a unified diff.
01167 
01168     Unified diffs are a compact way of showing line changes and a few
01169     lines of context.  The number of context lines is set by 'n' which
01170     defaults to three.
01171 
01172     By default, the diff control lines (those with ---, +++, or @@) are
01173     created with a trailing newline.  This is helpful so that inputs
01174     created from file.readlines() result in diffs that are suitable for
01175     file.writelines() since both the inputs and outputs have trailing
01176     newlines.
01177 
01178     For inputs that do not have trailing newlines, set the lineterm
01179     argument to "" so that the output will be uniformly newline free.
01180 
01181     The unidiff format normally has a header for filenames and modification
01182     times.  Any or all of these may be specified using strings for
01183     'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
01184     The modification times are normally expressed in the ISO 8601 format.
01185 
01186     Example:
01187 
01188     >>> for line in unified_diff('one two three four'.split(),
01189     ...             'zero one tree four'.split(), 'Original', 'Current',
01190     ...             '2005-01-26 23:30:50', '2010-04-02 10:20:52',
01191     ...             lineterm=''):
01192     ...     print(line)                 # doctest: +NORMALIZE_WHITESPACE
01193     --- Original        2005-01-26 23:30:50
01194     +++ Current         2010-04-02 10:20:52
01195     @@ -1,4 +1,4 @@
01196     +zero
01197      one
01198     -two
01199     -three
01200     +tree
01201      four
01202     """
01203 
01204     started = False
01205     for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
01206         if not started:
01207             started = True
01208             fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
01209             todate = '\t{}'.format(tofiledate) if tofiledate else ''
01210             yield '--- {}{}{}'.format(fromfile, fromdate, lineterm)
01211             yield '+++ {}{}{}'.format(tofile, todate, lineterm)
01212 
01213         first, last = group[0], group[-1]
01214         file1_range = _format_range_unified(first[1], last[2])
01215         file2_range = _format_range_unified(first[3], last[4])
01216         yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
01217 
01218         for tag, i1, i2, j1, j2 in group:
01219             if tag == 'equal':
01220                 for line in a[i1:i2]:
01221                     yield ' ' + line
01222                 continue
01223             if tag in {'replace', 'delete'}:
01224                 for line in a[i1:i2]:
01225                     yield '-' + line
01226             if tag in {'replace', 'insert'}:
01227                 for line in b[j1:j2]:
01228                     yield '+' + line
01229 

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Initial value:
00001 ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher',
00002            'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff',
00003            'unified_diff', 'HtmlDiff', 'Match']

Definition at line 31 of file difflib.py.

Initial value:
00001 """
00002 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
00003           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
00004 
00005 <html>
00006 
00007 <head>
00008     <meta http-equiv="Content-Type"
00009           content="text/html; charset=ISO-8859-1" />
00010     <title></title>
00011     <style type="text/css">%(styles)s
00012     </style>
00013 </head>
00014 
00015 <body>
00016     %(table)s%(legend)s
00017 </body>
00018 
00019 </html>"""

Definition at line 1621 of file difflib.py.

Initial value:
00001 """
00002     <table class="diff" summary="Legends">
00003         <tr> <th colspan="2"> Legends </th> </tr>
00004         <tr> <td> <table border="" summary="Colors">
00005                       <tr><th> Colors </th> </tr>
00006                       <tr><td class="diff_add">&nbsp;Added&nbsp;</td></tr>
00007                       <tr><td class="diff_chg">Changed</td> </tr>
00008                       <tr><td class="diff_sub">Deleted</td> </tr>
00009                   </table></td>
00010              <td> <table border="" summary="Links">
00011                       <tr><th colspan="2"> Links </th> </tr>
00012                       <tr><td>(f)irst change</td> </tr>
00013                       <tr><td>(n)ext change</td> </tr>
00014                       <tr><td>(t)op</td> </tr>
00015                   </table></td> </tr>
00016     </table>"""

Definition at line 1660 of file difflib.py.

Initial value:
00001 """
00002         table.diff {font-family:Courier; border:medium;}
00003         .diff_header {background-color:#e0e0e0}
00004         td.diff_header {text-align:right}
00005         .diff_next {background-color:#c0c0c0}
00006         .diff_add {background-color:#aaffaa}
00007         .diff_chg {background-color:#ffff77}
00008         .diff_sub {background-color:#ffaaaa}"""

Definition at line 1641 of file difflib.py.

Initial value:
00001 """
00002     <table class="diff" id="difflib_chg_%(prefix)s_top"
00003            cellspacing="0" cellpadding="0" rules="groups" >
00004         <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
00005         <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
00006         %(header_row)s
00007         <tbody>
00008 %(data_rows)s        </tbody>
00009     </table>"""

Definition at line 1650 of file difflib.py.

tuple difflib.Match = _namedtuple('Match', 'a b size')

Definition at line 39 of file difflib.py.