Commit 4ccc3d59 authored by Raymond Hettinger's avatar Raymond Hettinger

Doctest now examines all docstrings by default. Previously, it would

skip over functions with private names (as indicated by the underscore
naming convention).  The old default created too much of a risk that
user tests were being skipped inadvertently.  Note, this change could
break code in the unlikely case that someone had intentionally put
failing tests in the docstrings of private functions.  The breakage
is easily fixable by specifying the old behavior when calling testmod()
or Tester().  The more likely case is that the silent failure was
unintended and that the user needed to be informed so the test could be
fixed.
parent 368a0276
...@@ -190,15 +190,16 @@ attempted. ...@@ -190,15 +190,16 @@ attempted.
See \file{docstring.py} for all the details. They're unsurprising: the See \file{docstring.py} for all the details. They're unsurprising: the
module docstring, and all function, class and method docstrings are module docstring, and all function, class and method docstrings are
searched, with the exception of docstrings attached to objects with private searched. Optionally, the tester can be directed to exclude
names. Objects imported into the module are not searched. docstrings attached to objects with private names.
Objects imported into the module are not searched.
In addition, if \code{M.__test__} exists and "is true", it must be a In addition, if \code{M.__test__} exists and "is true", it must be a
dict, and each entry maps a (string) name to a function object, class dict, and each entry maps a (string) name to a function object, class
object, or string. Function and class object docstrings found from object, or string. Function and class object docstrings found from
\code{M.__test__} are searched even if the name is private, and \code{M.__test__} are searched even if the the tester has been
strings are searched directly as if they were docstrings. In output, directly to skip over private names in the rest of the module.
a key \code{K} in \code{M.__test__} appears with name In output, a key \code{K} in \code{M.__test__} appears with name
\begin{verbatim} \begin{verbatim}
<name of M>.__test__.K <name of M>.__test__.K
...@@ -206,7 +207,7 @@ a key \code{K} in \code{M.__test__} appears with name ...@@ -206,7 +207,7 @@ a key \code{K} in \code{M.__test__} appears with name
Any classes found are recursively searched similarly, to test docstrings in Any classes found are recursively searched similarly, to test docstrings in
their contained methods and nested classes. While private names reached their contained methods and nested classes. While private names reached
from \module{M}'s globals are skipped, all names reached from from \module{M}'s globals can be optionally skipped, all names reached from
\code{M.__test__} are searched. \code{M.__test__} are searched.
\subsection{What's the Execution Context?} \subsection{What's the Execution Context?}
......
...@@ -48,10 +48,10 @@ WHICH DOCSTRINGS ARE EXAMINED? ...@@ -48,10 +48,10 @@ WHICH DOCSTRINGS ARE EXAMINED?
+ M.__doc__. + M.__doc__.
+ f.__doc__ for all functions f in M.__dict__.values(), except those + f.__doc__ for all functions f in M.__dict__.values(), except those
with private names and those defined in other modules. defined in other modules.
+ C.__doc__ for all classes C in M.__dict__.values(), except those with + C.__doc__ for all classes C in M.__dict__.values(), except those
private names and those defined in other modules. defined in other modules.
+ If M.__test__ exists and "is true", it must be a dict, and + If M.__test__ exists and "is true", it must be a dict, and
each entry maps a (string) name to a function object, class object, or each entry maps a (string) name to a function object, class object, or
...@@ -62,13 +62,16 @@ WHICH DOCSTRINGS ARE EXAMINED? ...@@ -62,13 +62,16 @@ WHICH DOCSTRINGS ARE EXAMINED?
<name of M>.__test__.K <name of M>.__test__.K
Any classes found are recursively searched similarly, to test docstrings in Any classes found are recursively searched similarly, to test docstrings in
their contained methods and nested classes. Private names reached from M's their contained methods and nested classes. All names reached from
globals are skipped, but all names reached from M.__test__ are searched. M.__test__ are searched.
By default, a name is considered to be private if it begins with an Optionally, functions with private names can be skipped (unless listed in
underscore (like "_my_func") but doesn't both begin and end with (at least) M.__test__) by supplying a function to the "isprivate" argument that will
two underscores (like "__init__"). You can change the default by passing identify private functions. For convenience, one such function is
your own "isprivate" function to testmod. supplied. docttest.is_private considers a name to be private if it begins
with an underscore (like "_my_func") but doesn't both begin and end with
(at least) two underscores (like "__init__"). By supplying this function
or your own "isprivate" function to testmod, the behavior can be customized.
If you want to test docstrings in objects with private names too, stuff If you want to test docstrings in objects with private names too, stuff
them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your
...@@ -671,8 +674,10 @@ Optional keyword arg "verbose" prints lots of stuff if true, only ...@@ -671,8 +674,10 @@ Optional keyword arg "verbose" prints lots of stuff if true, only
failures if false; by default, it's true iff "-v" is in sys.argv. failures if false; by default, it's true iff "-v" is in sys.argv.
Optional keyword arg "isprivate" specifies a function used to determine Optional keyword arg "isprivate" specifies a function used to determine
whether a name is private. The default function is doctest.is_private; whether a name is private. The default function is to assume that
see its docs for details. no functions are private. The "isprivate" arg may be set to
doctest.is_private in order to skip over functions marked as private
using an underscore naming convention; see its docs for details.
See doctest.testmod docs for the meaning of optionflags. See doctest.testmod docs for the meaning of optionflags.
""" """
...@@ -691,8 +696,9 @@ See doctest.testmod docs for the meaning of optionflags. ...@@ -691,8 +696,9 @@ See doctest.testmod docs for the meaning of optionflags.
verbose = "-v" in sys.argv verbose = "-v" in sys.argv
self.verbose = verbose self.verbose = verbose
# By default, assume that nothing is private
if isprivate is None: if isprivate is None:
isprivate = is_private isprivate = lambda prefix, base: 0
self.isprivate = isprivate self.isprivate = isprivate
self.optionflags = optionflags self.optionflags = optionflags
...@@ -861,26 +867,26 @@ See doctest.testmod docs for the meaning of optionflags. ...@@ -861,26 +867,26 @@ See doctest.testmod docs for the meaning of optionflags.
Tests that objects outside m1 are excluded: Tests that objects outside m1 are excluded:
>>> t = Tester(globs={}, verbose=0) >>> t = Tester(globs={}, verbose=0, isprivate=is_private)
>>> t.rundict(m1.__dict__, "rundict_test", m1) # _f, f2 and g2 and h2 skipped >>> t.rundict(m1.__dict__, "rundict_test", m1) # _f, f2 and g2 and h2 skipped
(0, 3) (0, 3)
Again, but with a custom isprivate function allowing _f: Again, but with the default isprivate function allowing _f:
>>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 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_pvt", m1) # Only f2, g2 and h2 skipped
(0, 4) (0, 4)
And once more, not excluding stuff outside m1: And once more, not excluding stuff outside m1:
>>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 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.
(0, 8) (0, 8)
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) >>> testmod(m1, isprivate=is_private)
(0, 3) (0, 3)
""" """
...@@ -1070,7 +1076,8 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None, ...@@ -1070,7 +1076,8 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
Test examples in docstrings in functions and classes reachable Test examples in docstrings in functions and classes reachable
from module m (or the current module if m is not supplied), starting from module m (or the current module if m is not supplied), starting
with m.__doc__. Private names are skipped. with m.__doc__. Unless isprivate is specified, private names
are not skipped.
Also test examples reachable from dict m.__test__ if it exists and is Also test examples reachable from dict m.__test__ if it exists and is
not None. m.__dict__ maps names to functions, classes and strings; not None. m.__dict__ maps names to functions, classes and strings;
...@@ -1094,7 +1101,9 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None, ...@@ -1094,7 +1101,9 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
Optional keyword arg "isprivate" specifies a function used to Optional keyword arg "isprivate" specifies a function used to
determine whether a name is private. The default function is determine whether a name is private. The default function is
doctest.is_private; see its docs for details. 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
......
...@@ -38,6 +38,15 @@ Extension modules ...@@ -38,6 +38,15 @@ Extension modules
Library Library
------- -------
- doctest now examines all docstrings by default. Previously, it would
skip over functions with private names (as indicated by the underscore
naming convention). The old default created too much of a risk that
user tests were being skipped inadvertently. Note, this change could
break code in the unlikely case that someone had intentionally put
failing tests in the docstrings of private functions. The breakage
is easily fixable by specifying the old behavior when calling testmod()
or Tester().
- Closing a dumbdbm database more than once is now harmless (it used to - Closing a dumbdbm database more than once is now harmless (it used to
raise a nuisance exception on the second close). raise a nuisance exception on the second close).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment