[Python-checkins] CVS: python/dist/src/Lib difflib.py,1.4,1.5

Tim Peters tim_one@users.sourceforge.net
Sat, 22 Sep 2001 14:30:24 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv24440/python/Lib

Modified Files:
	difflib.py 
Log Message:
Make difflib.ndiff() and difflib.Differ.compare() generators.  This
restores the 2.1 ability of Tools/scripts/ndiff.py to start producing
output before the entire comparison is complete.


Index: difflib.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/difflib.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** difflib.py	2001/08/12 22:25:01	1.4
--- difflib.py	2001/09/22 21:30:22	1.5
***************
*** 1,4 ****
--- 1,6 ----
  #! /usr/bin/env python
  
+ from __future__ import generators
+ 
  """
  Module difflib -- helpers for computing deltas between objects.
***************
*** 23,28 ****
             'Differ']
  
- TRACE = 0
- 
  class SequenceMatcher:
  
--- 25,28 ----
***************
*** 407,413 ****
              bestsize = bestsize + 1
  
-         if TRACE:
-             print "get_matching_blocks", alo, ahi, blo, bhi
-             print "    returns", besti, bestj, bestsize
          return besti, bestj, bestsize
  
--- 407,410 ----
***************
*** 433,438 ****
          self.__helper(0, la, 0, lb, self.matching_blocks)
          self.matching_blocks.append( (la, lb, 0) )
-         if TRACE:
-             print '*** matching blocks', self.matching_blocks
          return self.matching_blocks
  
--- 430,433 ----
***************
*** 695,699 ****
      Finally, we compare the two:
  
!     >>> result = d.compare(text1, text2)
  
      'result' is a list of strings, so let's pretty-print it:
--- 690,694 ----
      Finally, we compare the two:
  
!     >>> result = list(d.compare(text1, text2))
  
      'result' is a list of strings, so let's pretty-print it:
***************
*** 732,736 ****
  
      compare(a, b)
!         Compare two sequences of lines; return the resulting delta (list).
      """
  
--- 727,731 ----
  
      compare(a, b)
!         Compare two sequences of lines; generate the resulting delta.
      """
  
***************
*** 754,767 ****
          self.linejunk = linejunk
          self.charjunk = charjunk
-         self.results = []
  
      def compare(self, a, b):
          r"""
!         Compare two sequences of lines; return the resulting delta (list).
  
          Each sequence must contain individual single-line strings ending with
          newlines. Such sequences can be obtained from the `readlines()` method
!         of file-like objects. The list returned is also made up of
!         newline-terminated strings, ready to be used with the `writelines()`
          method of a file-like object.
  
--- 749,761 ----
          self.linejunk = linejunk
          self.charjunk = charjunk
  
      def compare(self, a, b):
          r"""
!         Compare two sequences of lines; generate the resulting delta.
  
          Each sequence must contain individual single-line strings ending with
          newlines. Such sequences can be obtained from the `readlines()` method
!         of file-like objects.  The delta generated also consists of newline-
!         terminated strings, ready to be printed as-is via the writeline()
          method of a file-like object.
  
***************
*** 784,804 ****
          for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
              if tag == 'replace':
!                 self._fancy_replace(a, alo, ahi, b, blo, bhi)
              elif tag == 'delete':
!                 self._dump('-', a, alo, ahi)
              elif tag == 'insert':
!                 self._dump('+', b, blo, bhi)
              elif tag == 'equal':
!                 self._dump(' ', a, alo, ahi)
              else:
                  raise ValueError, 'unknown tag ' + `tag`
-         results = self.results
-         self.results = []
-         return results
  
      def _dump(self, tag, x, lo, hi):
!         """Store comparison results for a same-tagged range."""
          for i in xrange(lo, hi):
!             self.results.append('%s %s' % (tag, x[i]))
  
      def _plain_replace(self, a, alo, ahi, b, blo, bhi):
--- 778,798 ----
          for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
              if tag == 'replace':
!                 g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
              elif tag == 'delete':
!                 g = self._dump('-', a, alo, ahi)
              elif tag == 'insert':
!                 g = self._dump('+', b, blo, bhi)
              elif tag == 'equal':
!                 g = self._dump(' ', a, alo, ahi)
              else:
                  raise ValueError, 'unknown tag ' + `tag`
  
+             for line in g:
+                 yield line
+ 
      def _dump(self, tag, x, lo, hi):
!         """Generate comparison results for a same-tagged range."""
          for i in xrange(lo, hi):
!             yield '%s %s' % (tag, x[i])
  
      def _plain_replace(self, a, alo, ahi, b, blo, bhi):
***************
*** 807,815 ****
          # memory if the blocks are of very different sizes
          if bhi - blo < ahi - alo:
!             self._dump('+', b, blo, bhi)
!             self._dump('-', a, alo, ahi)
          else:
!             self._dump('-', a, alo, ahi)
!             self._dump('+', b, blo, bhi)
  
      def _fancy_replace(self, a, alo, ahi, b, blo, bhi):
--- 801,813 ----
          # memory if the blocks are of very different sizes
          if bhi - blo < ahi - alo:
!             first  = self._dump('+', b, blo, bhi)
!             second = self._dump('-', a, alo, ahi)
          else:
!             first  = self._dump('-', a, alo, ahi)
!             second = self._dump('+', b, blo, bhi)
! 
!         for g in first, second:
!             for line in g:
!                 yield line
  
      def _fancy_replace(self, a, alo, ahi, b, blo, bhi):
***************
*** 831,840 ****
          """
  
-         if TRACE:
-             self.results.append('*** _fancy_replace %s %s %s %s\n'
-                                 % (alo, ahi, blo, bhi))
-             self._dump('>', a, alo, ahi)
-             self._dump('<', b, blo, bhi)
- 
          # don't synch up unless the lines have a similarity score of at
          # least cutoff; best_ratio tracks the best score seen so far
--- 829,832 ----
***************
*** 870,874 ****
              if eqi is None:
                  # no identical pair either -- treat it as a straight replace
!                 self._plain_replace(a, alo, ahi, b, blo, bhi)
                  return
              # no close pair, but an identical pair -- synch up on that
--- 862,867 ----
              if eqi is None:
                  # no identical pair either -- treat it as a straight replace
!                 for line in self._plain_replace(a, alo, ahi, b, blo, bhi):
!                     yield line
                  return
              # no close pair, but an identical pair -- synch up on that
***************
*** 880,891 ****
          # a[best_i] very similar to b[best_j]; eqi is None iff they're not
          # identical
-         if TRACE:
-             self.results.append('*** best_ratio %s %s %s %s\n'
-                                 % (best_ratio, best_i, best_j))
-             self._dump('>', a, best_i, best_i+1)
-             self._dump('<', b, best_j, best_j+1)
  
          # pump out diffs from before the synch point
!         self._fancy_helper(a, alo, best_i, b, blo, best_j)
  
          # do intraline marking on the synch pair
--- 873,880 ----
          # a[best_i] very similar to b[best_j]; eqi is None iff they're not
          # identical
  
          # pump out diffs from before the synch point
!         for line in self._fancy_helper(a, alo, best_i, b, blo, best_j):
!             yield line
  
          # do intraline marking on the synch pair
***************
*** 909,929 ****
                  else:
                      raise ValueError, 'unknown tag ' + `tag`
!             self._qformat(aelt, belt, atags, btags)
          else:
              # the synch pair is identical
!             self.results.append('  ' + aelt)
  
          # pump out diffs from after the synch point
!         self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi)
  
      def _fancy_helper(self, a, alo, ahi, b, blo, bhi):
          if alo < ahi:
              if blo < bhi:
!                 self._fancy_replace(a, alo, ahi, b, blo, bhi)
              else:
!                 self._dump('-', a, alo, ahi)
          elif blo < bhi:
!             self._dump('+', b, blo, bhi)
  
      def _qformat(self, aline, bline, atags, btags):
          r"""
--- 898,924 ----
                  else:
                      raise ValueError, 'unknown tag ' + `tag`
!             for line in self._qformat(aelt, belt, atags, btags):
!                 yield line
          else:
              # the synch pair is identical
!             yield '  ' + aelt
  
          # pump out diffs from after the synch point
!         for line in self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi):
!             yield line
  
      def _fancy_helper(self, a, alo, ahi, b, blo, bhi):
+         g = []
          if alo < ahi:
              if blo < bhi:
!                 g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
              else:
!                 g = self._dump('-', a, alo, ahi)
          elif blo < bhi:
!             g = self._dump('+', b, blo, bhi)
  
+         for line in g:
+             yield line
+ 
      def _qformat(self, aline, bline, atags, btags):
          r"""
***************
*** 950,960 ****
          btags = btags[common:].rstrip()
  
!         self.results.append("- " + aline)
          if atags:
!             self.results.append("? %s%s\n" % ("\t" * common, atags))
  
!         self.results.append("+ " + bline)
          if btags:
!             self.results.append("? %s%s\n" % ("\t" * common, btags))
  
  # With respect to junk, an earlier version of ndiff simply refused to
--- 945,955 ----
          btags = btags[common:].rstrip()
  
!         yield "- " + aline
          if atags:
!              yield "? %s%s\n" % ("\t" * common, atags)
  
!         yield "+ " + bline
          if btags:
!             yield "? %s%s\n" % ("\t" * common, btags)
  
  # With respect to junk, an earlier version of ndiff simply refused to
***************
*** 1051,1055 ****
  def restore(delta, which):
      r"""
!     Return one of the two sequences that generated a delta.
  
      Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract
--- 1046,1050 ----
  def restore(delta, which):
      r"""
!     Generate one of the two sequences that generated a delta.
  
      Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract
***************
*** 1061,1064 ****
--- 1056,1060 ----
      >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
      ...              'ore\ntree\nemu\n'.splitlines(1))
+     >>> diff = list(diff)
      >>> print ''.join(restore(diff, 1)),
      one
***************
*** 1076,1084 ****
                             % which)
      prefixes = ("  ", tag)
-     results = []
      for line in delta:
          if line[:2] in prefixes:
!             results.append(line[2:])
!     return results
  
  def _test():
--- 1072,1078 ----
                             % which)
      prefixes = ("  ", tag)
      for line in delta:
          if line[:2] in prefixes:
!             yield line[2:]
  
  def _test():