*** Old/doctest.py	Sat Mar 27 21:40:20 1999
--- New/doctest.py	Sat Mar 27 21:34:00 1999
***************
*** 1,5 ****
! # Module doctest version 0.9.3
! # Released to the public domain 18-Mar-1999,
  # by Tim Peters (tim_one@email.msn.com).
  
  # Provided as-is; use at your own risk; no warranty; no promises; enjoy!
--- 1,5 ----
! # Module doctest version 0.9.4
! # Released to the public domain 27-Mar-1999,
  # by Tim Peters (tim_one@email.msn.com).
  
  # Provided as-is; use at your own risk; no warranty; no promises; enjoy!
***************
*** 316,323 ****
  #    minor internal changes
  #    changed source to Unix line-end conventions
  #    moved __test__ logic into new Tester.run__test__ method
  
! __version__ = 0, 9, 3
  
  import types
  _FunctionType = types.FunctionType
--- 316,325 ----
  #    minor internal changes
  #    changed source to Unix line-end conventions
  #    moved __test__ logic into new Tester.run__test__ method
+ # 0,9,4    27-Mar-1999
+ #    report item name and line # in failing examples
  
! __version__ = 0, 9, 4
  
  import types
  _FunctionType = types.FunctionType
***************
*** 342,352 ****
  _isComment = re.compile(r"\s*#").match
  del re
  
! # Extract interactive examples from a string.  Return a list of string
! # pairs, (source, outcome).  "source" is the source code, and ends
  # with a newline iff the source spans more than one line.  "outcome" is
  # the expected output if any, else an empty string.  When not empty,
! # outcome always ends with a newline.
  
  def _extract_examples(s):
      isPS1, isPS2 = _isPS1, _isPS2
--- 344,355 ----
  _isComment = re.compile(r"\s*#").match
  del re
  
! # Extract interactive examples from a string.  Return a list of triples,
! # (source, outcome, lineno).  "source" is the source code, and ends
  # with a newline iff the source spans more than one line.  "outcome" is
  # the expected output if any, else an empty string.  When not empty,
! # outcome always ends with a newline.  "lineno" is the line number,
! # 0-based wrt the start of the string, of the first source line.
  
  def _extract_examples(s):
      isPS1, isPS2 = _isPS1, _isPS2
***************
*** 364,371 ****
          if isEmpty(line, j) or isComment(line, j):
              # a bare prompt or comment -- not interesting
              continue
          if line[j] != " ":
!             raise ValueError("line " + `i-1` + " of docstring lacks "
                  "blank after " + PS1 + ": " + line)
          j = j + 1
          blanks = m.group(1)
--- 367,375 ----
          if isEmpty(line, j) or isComment(line, j):
              # a bare prompt or comment -- not interesting
              continue
+         lineno = i - 1
          if line[j] != " ":
!             raise ValueError("line " + `lineno` + " of docstring lacks "
                  "blank after " + PS1 + ": " + line)
          j = j + 1
          blanks = m.group(1)
***************
*** 405,411 ****
                  if isPS1(line) or isEmpty(line):
                      break
              expect = _string_join(expect, "\n") + "\n"
!         examples.append( (source, expect) )
      return examples
  
  # Capture stdout when running examples.
--- 409,415 ----
                  if isPS1(line) or isEmpty(line):
                      break
              expect = _string_join(expect, "\n") + "\n"
!         examples.append( (source, expect, lineno) )
      return examples
  
  # Capture stdout when running examples.
***************
*** 444,456 ****
  # stuff to "the real" stdout, and fakeout is an instance of _SpoofOut
  # that captures the examples' std output.  Return (#failures, #tries).
  
! def _run_examples_inner(out, fakeout, examples, globs, verbose):
      import sys, traceback
      OK, BOOM, FAIL = range(3)
      NADA = "nothing"
      stderr = _SpoofOut()
      failures = 0
!     for source, want in examples:
          if verbose:
              _tag_out(out, ("Trying", source),
                            ("Expecting", want or NADA))
--- 448,460 ----
  # stuff to "the real" stdout, and fakeout is an instance of _SpoofOut
  # that captures the examples' std output.  Return (#failures, #tries).
  
! def _run_examples_inner(out, fakeout, examples, globs, verbose, name):
      import sys, traceback
      OK, BOOM, FAIL = range(3)
      NADA = "nothing"
      stderr = _SpoofOut()
      failures = 0
!     for source, want, lineno in examples:
          if verbose:
              _tag_out(out, ("Trying", source),
                            ("Expecting", want or NADA))
***************
*** 475,480 ****
--- 479,485 ----
          failures = failures + 1
          out("*" * 65 + "\n")
          _tag_out(out, ("Failure in example", source))
+         out("from line #" + `lineno` + " of " + name + "\n")
          if state == FAIL:
              _tag_out(out, ("Expected", want or NADA), ("Got", got))
          else:
***************
*** 485,509 ****
  
  # Run list of examples, in context globs.  Return (#failures, #tries).
  
! def _run_examples(examples, globs, verbose):
      import sys
      saveout = sys.stdout
      try:
          sys.stdout = fakeout = _SpoofOut()
          x = _run_examples_inner(saveout.write, fakeout, examples,
!                                 globs, verbose)
      finally:
          sys.stdout = saveout
      return x
  
! def run_docstring_examples(f, globs, verbose=0):
!     """f, globs [,verbose] -> run examples from f.__doc__.
  
      Use dict globs as the globals for execution.
      Return (#failures, #tries).
  
      If optional arg verbose is true, print stuff even if there are no
      failures.
      """
  
      try:
--- 490,515 ----
  
  # Run list of examples, in context globs.  Return (#failures, #tries).
  
! def _run_examples(examples, globs, verbose, name):
      import sys
      saveout = sys.stdout
      try:
          sys.stdout = fakeout = _SpoofOut()
          x = _run_examples_inner(saveout.write, fakeout, examples,
!                                 globs, verbose, name)
      finally:
          sys.stdout = saveout
      return x
  
! def run_docstring_examples(f, globs, verbose=0, name="NoName"):
!     """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__.
  
      Use dict globs as the globals for execution.
      Return (#failures, #tries).
  
      If optional arg verbose is true, print stuff even if there are no
      failures.
+     Use string name in failure msgs.
      """
  
      try:
***************
*** 520,526 ****
      e = _extract_examples(doc)
      if not e:
          return 0, 0
!     return _run_examples(e, globs, verbose)
  
  def is_private(prefix, base):
      """prefix, base -> true iff name prefix + "." + base is "private".
--- 526,532 ----
      e = _extract_examples(doc)
      if not e:
          return 0, 0
!     return _run_examples(e, globs, verbose, name)
  
  def is_private(prefix, base):
      """prefix, base -> true iff name prefix + "." + base is "private".
***************
*** 585,593 ****
  ...      >>> x = x * 2
  ...      >>> print x
  ...      42
! ... ''', 'example')
  *****************************************************************
  Failure in example: print x
  Expected: 42
  Got: 84
  (1, 2)
--- 591,600 ----
  ...      >>> x = x * 2
  ...      >>> print x
  ...      42
! ... ''', 'XYZ')
  *****************************************************************
  Failure in example: print x
+ from line #2 of XYZ
  Expected: 42
  Got: 84
  (1, 2)
***************
*** 595,608 ****
  (0, 2)
  >>> t.summarize()
  1 items had failures:
!    1 of   2 in example
  ***Test Failed*** 1 failures.
  (1, 4)
  >>> t.summarize(verbose=1)
  1 items passed all tests:
     2 tests in example2
  1 items had failures:
!    1 of   2 in example
  4 tests in 2 items.
  3 passed and 1 failed.
  ***Test Failed*** 1 failures.
--- 602,615 ----
  (0, 2)
  >>> t.summarize()
  1 items had failures:
!    1 of   2 in XYZ
  ***Test Failed*** 1 failures.
  (1, 4)
  >>> t.summarize(verbose=1)
  1 items passed all tests:
     2 tests in example2
  1 items had failures:
!    1 of   2 in XYZ
  4 tests in 2 items.
  3 passed and 1 failed.
  ***Test Failed*** 1 failures.
***************
*** 634,640 ****
  see its docs for details.
  """
  
!         if mod is None is globs:
              raise TypeError("Tester.__init__: must specify mod or globs")
          if mod is not None and type(mod) is not _ModuleType:
              raise TypeError("Tester.__init__: mod must be a module; " +
--- 641,647 ----
  see its docs for details.
  """
  
!         if mod is None and globs is None:
              raise TypeError("Tester.__init__: must specify mod or globs")
          if mod is not None and type(mod) is not _ModuleType:
              raise TypeError("Tester.__init__: mod must be a module; " +
***************
*** 685,691 ****
          f = t = 0
          e = _extract_examples(s)
          if e:
!             f, t = _run_examples(e, self.globs.copy(), self.verbose)
          if self.verbose:
              print f, "of", t, "examples failed in string", name
          self.__record_outcome(name, f, t)
--- 692,698 ----
          f = t = 0
          e = _extract_examples(s)
          if e:
!             f, t = _run_examples(e, self.globs.copy(), self.verbose, name)
          if self.verbose:
              print f, "of", t, "examples failed in string", name
          self.__record_outcome(name, f, t)
***************
*** 724,730 ****
          if self.verbose:
              print "Running", name + ".__doc__"
          f, t = run_docstring_examples(object, self.globs.copy(),
!                                       self.verbose)
          if self.verbose:
              print f, "of", t, "examples failed in", name + ".__doc__"
          self.__record_outcome(name, f, t)
--- 731,737 ----
          if self.verbose:
              print "Running", name + ".__doc__"
          f, t = run_docstring_examples(object, self.globs.copy(),
!                                       self.verbose, name)
          if self.verbose:
              print f, "of", t, "examples failed in", name + ".__doc__"
          self.__record_outcome(name, f, t)
