[Python-checkins] python/dist/src/Lib doctest.py,1.44,1.45

tim_one at users.sourceforge.net tim_one at users.sourceforge.net
Sun Aug 8 08:11:50 CEST 2004


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

Modified Files:
	doctest.py 
Log Message:
Get rid of the ignore_imports argument to DocTestFinder.find().
This got slammed in when find() was fixed to stop grabbing doctests
from modules imported *by* the module being tested.  Such tests cannot
be expected to succeed, since they'll be run with the current module's
globals.  Dozens of Zope3 doctests were failing because of that.

It wasn't clear why ignore_imports got added then.  Maybe it's because
some existing tests failed when the change was made.  Whatever, it's
a Bad Idea so it's gone now.

The only use of it was exceedingly obscure, in test_doctest's "Duplicate
Removal" test.  It was "needed" there because, as an artifact of running
a doctest inside a doctest, the func_globals of functions compiled in
the second-level doctest don't match the module globals, and so the
test-finder believed these functions were from a foreign module and
skipped them.  But that took a long time to figure out, and I actually
understand some of this stuff <0.9 wink>.

That problem was resolved by moving the source code for the second-level
doctest into an actual module (test/doctest_aliases.py).

The only remaining difficulty was that the test for the deprecated
Tester.rundict() then failed, because the test finder doesn't take
module=None at face value, trying to guess which module the user really
intended then.  Its guess wasn't appropriate for what Tester.rundict
needs when module=None is given to *it*, which is "no, there is no
module here, and I mean it".  So now passing module=False means exactly
that.  This is hokey, but ignore_imports=False was really a hack to worm
around that there was no way to tell the test-finder that module=None
*sometimes* means what it says.  There was no use case for the combination
of passing a real module with ignore_imports=False.


Index: doctest.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v
retrieving revision 1.44
retrieving revision 1.45
diff -C2 -d -r1.44 -r1.45
*** doctest.py	8 Aug 2004 03:38:33 -0000	1.44
--- doctest.py	8 Aug 2004 06:11:47 -0000	1.45
***************
*** 809,813 ****
  
      def find(self, obj, name=None, module=None, globs=None,
!              extraglobs=None, ignore_imports=True):
          """
          Return a list of the DocTests that are defined by the given
--- 809,813 ----
  
      def find(self, obj, name=None, module=None, globs=None,
!              extraglobs=None):
          """
          Return a list of the DocTests that are defined by the given
***************
*** 816,831 ****
  
          The optional parameter `module` is the module that contains
!         the given object.  If the module is not specified, then the
!         test finder will attempt to automatically determine the
          correct module.  The object's module is used:
  
              - As a default namespace, if `globs` is not specified.
              - To prevent the DocTestFinder from extracting DocTests
!               from objects that are imported from other modules
!               (as long as `ignore_imports` is true).
              - To find the name of the file containing the object.
              - To help find the line number of the object within its
                file.
  
          The globals for each DocTest is formed by combining `globs`
          and `extraglobs` (bindings in `extraglobs` override bindings
--- 816,838 ----
  
          The optional parameter `module` is the module that contains
!         the given object.  If the module is not specified or is None, then
!         the test finder will attempt to automatically determine the
          correct module.  The object's module is used:
  
              - As a default namespace, if `globs` is not specified.
              - To prevent the DocTestFinder from extracting DocTests
!               from objects that are imported from other modules.
              - To find the name of the file containing the object.
              - To help find the line number of the object within its
                file.
  
+         Contained objects whose module does not match `module` are ignored.
+ 
+         If `module` is False, no attempt to find the module will be made.
+         This is obscure, of use mostly in tests:  if `module` is False, or
+         is None but cannot be found automatically, then all objects are
+         considered to belong to the (non-existent) module, so all contained
+         objects will (recursively) be searched for doctests.
+ 
          The globals for each DocTest is formed by combining `globs`
          and `extraglobs` (bindings in `extraglobs` override bindings
***************
*** 836,843 ****
          to {}.
  
-         If the optional flag `ignore_imports` is true, then the
-         doctest finder will ignore any contained objects whose module
-         does not match `module`.  Otherwise, it will extract tests
-         from all contained objects, including imported objects.
          """
          # If name was not specified, then extract it from the object.
--- 843,846 ----
***************
*** 852,856 ****
          # a module, then module=obj.).  Note: this may fail, in which
          # case module will be None.
!         if module is None:
              module = inspect.getmodule(obj)
  
--- 855,861 ----
          # a module, then module=obj.).  Note: this may fail, in which
          # case module will be None.
!         if module is False:
!             module = None
!         elif module is None:
              module = inspect.getmodule(obj)
  
***************
*** 879,884 ****
          # Recursively expore `obj`, extracting DocTests.
          tests = []
!         self._find(tests, obj, name, module, source_lines,
!                    globs, ignore_imports, {})
          return tests
  
--- 884,888 ----
          # Recursively expore `obj`, extracting DocTests.
          tests = []
!         self._find(tests, obj, name, module, source_lines, globs, {})
          return tests
  
***************
*** 910,915 ****
              raise ValueError("object must be a class or function")
  
!     def _find(self, tests, obj, name, module, source_lines,
!               globs, ignore_imports, seen):
          """
          Find tests for the given object and any contained objects, and
--- 914,918 ----
              raise ValueError("object must be a class or function")
  
!     def _find(self, tests, obj, name, module, source_lines, globs, seen):
          """
          Find tests for the given object and any contained objects, and
***************
*** 938,944 ****
                  # Recurse to functions & classes.
                  if ((inspect.isfunction(val) or inspect.isclass(val)) and
!                     (self._from_module(module, val) or not ignore_imports)):
                      self._find(tests, val, valname, module, source_lines,
!                                globs, ignore_imports, seen)
  
          # Look for tests in a module's __test__ dictionary.
--- 941,947 ----
                  # Recurse to functions & classes.
                  if ((inspect.isfunction(val) or inspect.isclass(val)) and
!                     self._from_module(module, val)):
                      self._find(tests, val, valname, module, source_lines,
!                                globs, seen)
  
          # Look for tests in a module's __test__ dictionary.
***************
*** 958,962 ****
                  valname = '%s.%s' % (name, valname)
                  self._find(tests, val, valname, module, source_lines,
!                            globs, ignore_imports, seen)
  
          # Look for tests in a class's contained objects.
--- 961,965 ----
                  valname = '%s.%s' % (name, valname)
                  self._find(tests, val, valname, module, source_lines,
!                            globs, seen)
  
          # Look for tests in a class's contained objects.
***************
*** 974,982 ****
                  # Recurse to methods, properties, and nested classes.
                  if ((inspect.isfunction(val) or inspect.isclass(val) or
!                     isinstance(val, property)) and
!                     (self._from_module(module, val) or not ignore_imports)):
                      valname = '%s.%s' % (name, valname)
                      self._find(tests, val, valname, module, source_lines,
!                                globs, ignore_imports, seen)
  
      def _get_test(self, obj, name, module, globs, source_lines):
--- 977,985 ----
                  # Recurse to methods, properties, and nested classes.
                  if ((inspect.isfunction(val) or inspect.isclass(val) or
!                       isinstance(val, property)) and
!                       self._from_module(module, val)):
                      valname = '%s.%s' % (name, valname)
                      self._find(tests, val, valname, module, source_lines,
!                                globs, seen)
  
      def _get_test(self, obj, name, module, globs, source_lines):
***************
*** 1895,1903 ****
          return (f,t)
  
!     def rundoc(self, object, name=None, module=None, ignore_imports=True):
          f = t = 0
          tests = self.testfinder.find(object, name, module=module,
!                                      globs=self.globs,
!                                      ignore_imports=ignore_imports)
          for test in tests:
              (f2, t2) = self.testrunner.run(test)
--- 1898,1905 ----
          return (f,t)
  
!     def rundoc(self, object, name=None, module=None):
          f = t = 0
          tests = self.testfinder.find(object, name, module=module,
!                                      globs=self.globs)
          for test in tests:
              (f2, t2) = self.testrunner.run(test)
***************
*** 1909,1914 ****
          m = new.module(name)
          m.__dict__.update(d)
!         ignore_imports = (module is not None)
!         return self.rundoc(m, name, module, ignore_imports)
  
      def run__test__(self, d, name):
--- 1911,1917 ----
          m = new.module(name)
          m.__dict__.update(d)
!         if module is None:
!             module = False
!         return self.rundoc(m, name, module)
  
      def run__test__(self, d, name):



More information about the Python-checkins mailing list