Deprecated testmod's useless & confusing isprivate gimmick.

Ripped out the docs for the new DocTestFinder's namefilter argument,
and renamed it to _namefilter; this only existed to support isprivate.
Removed the new DocTestFinder's objfilter argument.  No point adding
more cruft to a broken filtering design.
This commit is contained in:
Tim Peters 2004-08-08 01:48:59 +00:00
parent 9ca3f8551a
commit f727c6c2c7
2 changed files with 32 additions and 61 deletions

View file

@ -307,6 +307,7 @@ import __future__
import sys, traceback, inspect, linecache, os, re, types import sys, traceback, inspect, linecache, os, re, types
import unittest, difflib, tempfile import unittest, difflib, tempfile
import warnings
from StringIO import StringIO from StringIO import StringIO
# Option constants. # Option constants.
@ -778,25 +779,10 @@ class DocTestFinder:
objects. Doctests can currently be extracted from the following objects. Doctests can currently be extracted from the following
object types: modules, functions, classes, methods, staticmethods, object types: modules, functions, classes, methods, staticmethods,
classmethods, and properties. classmethods, and properties.
An optional name filter and an optional object filter may be
passed to the constructor, to restrict which contained objects are
examined by the doctest finder:
- The name filter is a function `f(prefix, base)`, that returns
true if an object named `prefix.base` should be ignored.
- The object filter is a function `f(obj)` that returns true
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.
""" """
def __init__(self, verbose=False, doctest_factory=DocTest, def __init__(self, verbose=False, doctest_factory=DocTest,
namefilter=None, objfilter=None, recurse=True): recurse=True, _namefilter=None):
""" """
Create a new doctest finder. Create a new doctest finder.
@ -811,9 +797,10 @@ class DocTestFinder:
""" """
self._doctest_factory = doctest_factory self._doctest_factory = doctest_factory
self._verbose = verbose self._verbose = verbose
self._namefilter = namefilter
self._objfilter = objfilter
self._recurse = recurse self._recurse = recurse
# _namefilter is undocumented, and exists only for temporary backward-
# compatibility support of testmod's deprecated isprivate mess.
self._namefilter = _namefilter
def find(self, obj, name=None, module=None, globs=None, def find(self, obj, name=None, module=None, globs=None,
extraglobs=None, ignore_imports=True): extraglobs=None, ignore_imports=True):
@ -894,10 +881,8 @@ class DocTestFinder:
""" """
Return true if the given object should not be examined. Return true if the given object should not be examined.
""" """
return ((self._namefilter is not None and return (self._namefilter is not None and
self._namefilter(prefix, base)) or self._namefilter(prefix, base))
(self._objfilter is not None and
self._objfilter(obj)))
def _from_module(self, module, object): def _from_module(self, module, object):
""" """
@ -1744,12 +1729,6 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
Optional keyword arg "verbose" prints lots of stuff if true, prints Optional keyword arg "verbose" prints lots of stuff if true, prints
only failures if false; by default, it's true iff "-v" is in sys.argv. only failures if false; by default, it's true iff "-v" is in sys.argv.
Optional keyword arg "isprivate" specifies a function used to
determine whether a name is private. The default function is
treat all functions as public. Optionally, "isprivate" can be
set to doctest.is_private to skip over functions marked as private
using the underscore naming convention; see its docs for details.
Optional keyword arg "report" prints a summary at the end when true, Optional keyword arg "report" prints a summary at the end when true,
else prints nothing at the end. In verbose mode, the summary is else prints nothing at the end. In verbose mode, the summary is
detailed, else very brief (in fact, empty if all tests passed). detailed, else very brief (in fact, empty if all tests passed).
@ -1796,6 +1775,12 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
first unexpected exception or failure. This allows failures to be first unexpected exception or failure. This allows failures to be
post-mortem debugged. post-mortem debugged.
Deprecated in Python 2.4:
Optional keyword arg "isprivate" specifies a function used to
determine whether a name is private. The default function is
treat all functions as public. Optionally, "isprivate" can be
set to doctest.is_private to skip over functions marked as private
using the underscore naming convention; see its docs for details.
""" """
""" [XX] This is no longer true: """ [XX] This is no longer true:
@ -1807,6 +1792,11 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
displaying a summary. Invoke doctest.master.summarize(verbose) displaying a summary. Invoke doctest.master.summarize(verbose)
when you're done fiddling. when you're done fiddling.
""" """
if isprivate is not None:
warnings.warn("the isprivate argument is deprecated; "
"examine DocTestFinder.find() lists instead",
DeprecationWarning)
# If no module was given, then use __main__. # If no module was given, then use __main__.
if m is None: if m is None:
# DWA - m will still be None if this wasn't invoked from the command # DWA - m will still be None if this wasn't invoked from the command
@ -1823,7 +1813,7 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
name = m.__name__ name = m.__name__
# Find, parse, and run all tests in the given module. # Find, parse, and run all tests in the given module.
finder = DocTestFinder(namefilter=isprivate) finder = DocTestFinder(_namefilter=isprivate)
if raise_on_error: if raise_on_error:
runner = DebugRunner(verbose=verbose, optionflags=optionflags) runner = DebugRunner(verbose=verbose, optionflags=optionflags)
@ -1882,7 +1872,7 @@ class Tester:
self.verbose = verbose self.verbose = verbose
self.isprivate = isprivate self.isprivate = isprivate
self.optionflags = optionflags self.optionflags = optionflags
self.testfinder = DocTestFinder(namefilter=isprivate) self.testfinder = DocTestFinder(_namefilter=isprivate)
self.testrunner = DocTestRunner(verbose=verbose, self.testrunner = DocTestRunner(verbose=verbose,
optionflags=optionflags) optionflags=optionflags)
@ -2494,17 +2484,11 @@ def test4(): """
Tests that objects outside m1 are excluded: Tests that objects outside m1 are excluded:
>>> t = Tester(globs={}, verbose=0, isprivate=is_private)
>>> t.rundict(m1.__dict__, "rundict_test", m1) # _f, f2 and g2 and h2 skipped
(0, 3)
Again, but with the default isprivate function allowing _f:
>>> t = Tester(globs={}, verbose=0) >>> t = Tester(globs={}, verbose=0)
>>> t.rundict(m1.__dict__, "rundict_test_pvt", m1) # Only f2, g2 and h2 skipped >>> t.rundict(m1.__dict__, "rundict_test", m1) # f2 and g2 and h2 skipped
(0, 4) (0, 4)
And once more, not excluding stuff outside m1: Once more, not excluding stuff outside m1:
>>> t = Tester(globs={}, verbose=0) >>> t = Tester(globs={}, verbose=0)
>>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped. >>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped.
@ -2513,8 +2497,8 @@ def test4(): """
The exclusion of objects from outside the designated module is The exclusion of objects from outside the designated module is
meant to be invoked automagically by testmod. meant to be invoked automagically by testmod.
>>> testmod(m1, isprivate=is_private, verbose=False) >>> testmod(m1, verbose=False)
(0, 3) (0, 4)
""" """
def _test(): def _test():

View file

@ -387,12 +387,13 @@ will only be generated for it once:
Filter Functions Filter Functions
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
Two filter functions can be used to restrict which objects get A filter function can be used to restrict which objects get examined,
examined: a name-based filter and an object-based filter. but this is temporary, undocumented internal support for testmod's
deprecated isprivate gimmick.
>>> def namefilter(prefix, base): >>> def namefilter(prefix, base):
... return base.startswith('a_') ... return base.startswith('a_')
>>> tests = doctest.DocTestFinder(namefilter=namefilter).find(SampleClass) >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass)
>>> tests.sort() >>> tests.sort()
>>> for t in tests: >>> for t in tests:
... print '%2s %s' % (len(t.examples), t.name) ... print '%2s %s' % (len(t.examples), t.name)
@ -403,26 +404,12 @@ examined: a name-based filter and an object-based filter.
1 SampleClass.double 1 SampleClass.double
1 SampleClass.get 1 SampleClass.get
>>> def objfilter(obj):
... return isinstance(obj, (staticmethod, classmethod))
>>> tests = doctest.DocTestFinder(objfilter=objfilter).find(SampleClass)
>>> tests.sort()
>>> for t in tests:
... print '%2s %s' % (len(t.examples), t.name)
1 SampleClass
3 SampleClass.NestedClass
1 SampleClass.NestedClass.__init__
1 SampleClass.__init__
1 SampleClass.a_property
1 SampleClass.double
1 SampleClass.get
If a given object is filtered out, then none of the objects that it If a given object is filtered out, then none of the objects that it
contains will be added either: contains will be added either:
>>> def namefilter(prefix, base): >>> def namefilter(prefix, base):
... return base == 'NestedClass' ... return base == 'NestedClass'
>>> tests = doctest.DocTestFinder(namefilter=namefilter).find(SampleClass) >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass)
>>> tests.sort() >>> tests.sort()
>>> for t in tests: >>> for t in tests:
... print '%2s %s' % (len(t.examples), t.name) ... print '%2s %s' % (len(t.examples), t.name)
@ -434,12 +421,12 @@ contains will be added either:
1 SampleClass.double 1 SampleClass.double
1 SampleClass.get 1 SampleClass.get
The filter functions apply to contained objects, and *not* to the The filter function apply to contained objects, and *not* to the
object explicitly passed to DocTestFinder: object explicitly passed to DocTestFinder:
>>> def namefilter(prefix, base): >>> def namefilter(prefix, base):
... return base == 'SampleClass' ... return base == 'SampleClass'
>>> tests = doctest.DocTestFinder(namefilter=namefilter).find(SampleClass) >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass)
>>> len(tests) >>> len(tests)
9 9
@ -1066,7 +1053,7 @@ def test_DocTestSuite():
poorly conceived, and will go away someday. poorly conceived, and will go away someday.
>>> finder = doctest.DocTestFinder( >>> finder = doctest.DocTestFinder(
... namefilter=lambda prefix, base: base!='bar') ... _namefilter=lambda prefix, base: base!='bar')
>>> suite = doctest.DocTestSuite('test.sample_doctest', >>> suite = doctest.DocTestSuite('test.sample_doctest',
... test_finder=finder) ... test_finder=finder)
>>> suite.run(unittest.TestResult()) >>> suite.run(unittest.TestResult())