[Python-checkins] python/dist/src/Lib doctest.py,1.36.2.2,1.36.2.3

edloper at users.sourceforge.net edloper at users.sourceforge.net
Tue Aug 3 06:08:55 CEST 2004


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5702

Modified Files:
      Tag: tim-doctest-branch
	doctest.py 
Log Message:
- Added support for "option directives", which can be used to control
  a doctest option from within a DocTest test case.
- Removed a debug printf
- Fixed blankline gimick to handle actual-output blank lines that
  contain only whitespace.
- When displaying output differences, don't display <BLANKLINE> in
  the output if the DONT_ACCEPT_BLANKLINE flag was used.
- When displaying output differences for exceptions, include the
  exception header ("Traceback (...):")


Index: doctest.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v
retrieving revision 1.36.2.2
retrieving revision 1.36.2.3
diff -C2 -d -r1.36.2.2 -r1.36.2.3
*** doctest.py	3 Aug 2004 03:37:59 -0000	1.36.2.2
--- doctest.py	3 Aug 2004 04:08:52 -0000	1.36.2.3
***************
*** 318,321 ****
--- 318,330 ----
  CONTEXT_DIFF = 1 << 5
  
+ OPTIONFLAGS_BY_NAME = {
+     'DONT_ACCEPT_TRUE_FOR_1': DONT_ACCEPT_TRUE_FOR_1,
+     'DONT_ACCEPT_BLANKLINE': DONT_ACCEPT_BLANKLINE,
+     'NORMALIZE_WHITESPACE': NORMALIZE_WHITESPACE,
+     'ELLIPSIS': ELLIPSIS,
+     'UNIFIED_DIFF': UNIFIED_DIFF,
+     'CONTEXT_DIFF': CONTEXT_DIFF,
+     }
+ 
  # Special string markers for use in `want` strings:
  BLANKLINE_MARKER = '<BLANKLINE>'
***************
*** 597,603 ****
          if the given object should be ignored.
  
!     These filter functions are applied when examining the contents of
!     a module or of a class, but not when examining a module's
!     `__test__` dictionary.  By default, no objects are ignored.
      """
  
--- 606,614 ----
          if the given object should be ignored.
  
!     Each object is ignored if either filter function returns true for
!     that object.  These filter functions are applied when examining
!     the contents of a module or of a class, but not when examining a
!     module's `__test__` dictionary.  By default, no objects are
!     ignored.
      """
  
***************
*** 694,698 ****
          if self._verbose:
              print 'Finding tests in %s' % name
-         print >>sys.stderr, 'Finding tests in %s' % name
  
          # If we've already processed this object, then ignore it.
--- 705,708 ----
***************
*** 950,955 ****
          # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
          if not (self._optionflags & DONT_ACCEPT_BLANKLINE):
!             want = re.sub('(?m)^%s$' % re.escape(BLANKLINE_MARKER),
                            '', want)
              if got == want: return True
  
--- 960,969 ----
          # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
          if not (self._optionflags & DONT_ACCEPT_BLANKLINE):
!             # Replace <BLANKLINE> in want with a blank line.
!             want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER),
                            '', want)
+             # If a line in got contains only spaces, then remove the
+             # spaces.
+             got = re.sub('(?m)^\s*?$', '', got)
              if got == want: return True
  
***************
*** 1012,1016 ****
          # output followed by the actual output.  But explicitly mark
          # blank lines in the actual output.
!         got = re.sub('(?m)^$(?!\Z)', '<BLANKLINE>', got)
          return (_tag_msg("Expected", want or "Nothing") +
                  _tag_msg("Got", got))
--- 1026,1031 ----
          # output followed by the actual output.  But explicitly mark
          # blank lines in the actual output.
!         if not (self._optionflags & DONT_ACCEPT_BLANKLINE):
!             got = re.sub('(?m)^$(?!\Z)', '<BLANKLINE>', got)
          return (_tag_msg("Expected", want or "Nothing") +
                  _tag_msg("Got", got))
***************
*** 1085,1093 ****
      # starting with word characters after the "Traceback ...".)
      _EXCEPTION_RE = re.compile(('^(?P<out>.*)'
!                                 '^Traceback \((?:%s|%s)\):\s*$.*?'
                                  '^(?P<exc>\w+.*)') %
                                 ('most recent call last', 'innermost last'),
                                 re.MULTILINE | re.DOTALL)
  
      def __run(self, test, globs, compileflags, out):
          """
--- 1100,1132 ----
      # starting with word characters after the "Traceback ...".)
      _EXCEPTION_RE = re.compile(('^(?P<out>.*)'
!                                 '^(?P<hdr>Traceback \((?:%s|%s)\):)\s*$.*?'
                                  '^(?P<exc>\w+.*)') %
                                 ('most recent call last', 'innermost last'),
                                 re.MULTILINE | re.DOTALL)
  
+     _OPTION_DIRECTIVE_RE = re.compile('\s*doctest:\s*(?P<flags>[^#]*)')
+ 
+     def __handle_directive(self, example):
+         """
+         Check if the given example is actually a directive to doctest
+         (to turn an optionflag on or off; and if it is, then handle
+         the directive.
+ 
+         Return true iff the example is actually a directive (and so
+         should not be executed).
+         """
+         m = self._OPTION_DIRECTIVE_RE.match(example.source)
+         if m is None: return False
+ 
+         for flag in m.group('flags').upper().split():
+             if (flag[:1] not in '+-' or
+                 flag[1:] not in OPTIONFLAGS_BY_NAME):
+                 raise ValueError('Bad doctest option directive: '+flag)
+             if flag[0] == '+':
+                 self._optionflags |= OPTIONFLAGS_BY_NAME[flag[1:]]
+             else:
+                 self._optionflags &= ~OPTIONFLAGS_BY_NAME[flag[1:]]
+         return True
+ 
      def __run(self, test, globs, compileflags, out):
          """
***************
*** 1103,1108 ****
--- 1142,1157 ----
          failures = tries = 0
  
+         # Save the option flags (since doctest directives can be used
+         # to modify them).
+         original_optionflags = self._optionflags
+ 
          # Process each example.
          for example in test.examples:
+             # Check if it's an option directive.  If it is, then handle
+             # it, and go on to the next example.
+             if self.__handle_directive(example):
+                 continue
+ 
+             # Record that we started this example.
              tries += 1
              self.report_start(out, test, example)
***************
*** 1150,1153 ****
--- 1199,1203 ----
                      failures += 1
                  else:
+                     exc_hdr = m.group('hdr')+'\n' # Exception header
                      # The test passes iff the pre-exception output and
                      # the exception description match the values given
***************
*** 1156,1164 ****
                          self.check_output(m.group('exc'), exc_msg)):
                          # Is +exc_msg the right thing here??
!                         self.report_success(out, test, example, got+exc_msg)
                      else:
!                         self.report_failure(out, test, example, got+exc_msg)
                          failures += 1
  
          # Record and return the number of failures and tries.
          self.__record_outcome(test, failures, tries)
--- 1206,1219 ----
                          self.check_output(m.group('exc'), exc_msg)):
                          # Is +exc_msg the right thing here??
!                         self.report_success(out, test, example,
!                                             got+exc_hdr+exc_msg)
                      else:
!                         self.report_failure(out, test, example,
!                                             got+exc_hdr+exc_msg)
                          failures += 1
  
+         # Restore the option flags (in case they were modified)
+         self._optionflags = original_optionflags
+ 
          # Record and return the number of failures and tries.
          self.__record_outcome(test, failures, tries)
***************
*** 1912,1916 ****
  Traceback (most recent call last):
  [...]
! ValueError:
  foo
  
--- 1967,1971 ----
  Traceback (most recent call last):
  [...]
! ValueError: 
  foo
  
***************
*** 1924,1929 ****
      #print '~'*70
      r = unittest.TextTestRunner()
!     r.run(DocTestSuite())#optionflags=ELLIPSIS | NORMALIZE_WHITESPACE |
! #                       UNIFIED_DIFF))
  
  if __name__ == "__main__":
--- 1979,1983 ----
      #print '~'*70
      r = unittest.TextTestRunner()
!     r.run(DocTestSuite())
  
  if __name__ == "__main__":



More information about the Python-checkins mailing list