Added a lot of new stuff to the debugging section.

This commit is contained in:
Tim Peters 2004-09-26 05:09:59 +00:00
parent 3afaaf2487
commit 05b05febad
1 changed files with 159 additions and 29 deletions

View File

@ -1547,34 +1547,174 @@ initialized by the constructor, and should not be modified directly.
\subsection{Debugging\label{doctest-debugging}} \subsection{Debugging\label{doctest-debugging}}
Doctest provides three mechanisms for debugging doctest examples: Doctest provides several mechanisms for debugging doctest examples:
\begin{enumerate} \begin{itemize}
\item The \function{debug()} function converts a specified doctest \item Several functions convert doctests to executable Python
to a Python script, and executes that script using \module{pdb}. programs, which can be run under the Python debugger, \refmodule{pdb}.
\item The \class{DebugRunner} class is a subclass of \item The \class{DebugRunner} class is a subclass of
\class{DocTestRunner} that raises an exception for the first \class{DocTestRunner} that raises an exception for the first
failing example, containing information about that example. failing example, containing information about that example.
This information can be used to perform post-mortem debugging on This information can be used to perform post-mortem debugging on
the example. the example.
\item The unittest cases generated by \function{DocTestSuite()} \item The \module{unittest} cases generated by \function{DocTestSuite()}
support the \method{debug} method defined by support the \method{debug()} method defined by
\class{unittest.TestCase}. \class{unittest.TestCase}.
\end{enumerate} \item You can add a call to \function{pdb.set_trace()} in a doctest
example, and you'll drop into the Python debugger when that
line is executed. Then you can inspect current values of variables,
and so on. For example, suppose \file{a.py} contains just this
module docstring:
\begin{funcdesc}{debug}{module, name} \begin{verbatim}
Debug a single doctest docstring. """
>>> def f(x):
... g(x*2)
>>> def g(x):
... print x+3
... import pdb; pdb.set_trace()
>>> f(3)
9
"""
\end{verbatim}
Provide the \var{module} (or dotted name of the module) containing Then an interactive Python session may look like this:
the docstring to be debugged and the fully qualified dotted
\var{name} of the object with the docstring to be debugged. \begin{verbatim}
>>> import a, doctest
>>> doctest.testmod(a)
--Return--
> <doctest a[1]>(3)g()->None
-> import pdb; pdb.set_trace()
(Pdb) list
1 def g(x):
2 print x+3
3 -> import pdb; pdb.set_trace()
[EOF]
(Pdb) print x
6
(Pdb) step
--Return--
> <doctest a[0]>(2)f()->None
-> g(x*2)
(Pdb) list
1 def f(x):
2 -> g(x*2)
[EOF]
(Pdb) print x
3
(Pdb) step
--Return--
> <doctest a[2]>(1)?()->None
-> f(3)
(Pdb) cont
(0, 3)
>>>
\end{verbatim}
\versionchanged[The ability to use \code{pdb.set_trace()} usefully
inside doctests was added]{2.4}
\end{itemize}
Functions that convert doctests to Python code, and possibly run
the synthesized code under the debugger:
\begin{funcdesc}{script_from_examples}{s}
Convert text with examples to a script.
Argument \var{s} is a string containing doctest examples. The string
is converted to a Python script, where doctest examples in \var{s}
are converted to regular code, and everything else is converted to
Python comments. The generated script is returned as a string.
For example, given file \file{a.py} as above,
\begin{verbatim}
>>> print doctest.script_from_examples(open("a.py").read())
# """
def f(x):
g(x*2)
def g(x):
print x+3
import pdb; pdb.set_trace()
f(3)
# Expected:
## 9
## """
\end{verbatim}
\versionadded{2.4}
\end{funcdesc}
\begin{funcdesc}{testsource}{module, name}
Convert the doctest for an object to a script.
Argument \var{module} is a module object, or dotted name of a module,
containing the object whose doctests are of interest. Argument
\var{name} is the name (within the module) of the object with the
doctests of interest. The result is a string, containing the
object's docstring converted to a Python script, as described for
\function{script_from_examples()} above. For example, if module
\file{a.py} contains a top-level function \function{f()}, then
\begin{verbatim}
import a, doctest
print doctest.testsource(a, "a.f")
\end{verbatim}
prints a script version of function \function{f()}'s docstring,
with doctests converted to code, and the rest placed in comments.
The doctest examples are extracted (see function \function{testsource()}),
and written to a temporary file. The Python debugger, \refmodule{pdb},
is then invoked on that file.
\versionadded{2.3} \versionadded{2.3}
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{debug}{module, name\optional{, pm}}
Debug the doctests for an object.
The \var{module} and \var{name} arguments are the same as for function
\function{testsource()} above. The synthesized Python script for the
named object's docstring is written to a temporary file, and then that
file is run under the control of the Python debugger, \refmodule{pdb}.
A shallow copy of \code{\var{module}.__dict__} is used for both local
and global execution context.
Optional argument \var{pm} controls whether post-mortem debugging is
used. If \var{pm} has a true value, the script file is run directly,
and the debugger gets involved only if the script terminates via raising
an unhandled exception. If it does, then post-mortem debugging is
invoked, via \code{pdb.post_mortem()}, passing the traceback object
from the unhandled exception. If \var{pm} is not specified, or is false,
the script is run under the debugger from the start, via passing an
appropriate \function{execfile()} call to \code{pdb.run()}.
\versionadded{2.3}
\versionchanged[The \var{pm} argument was added]{2.4}
\end{funcdesc}
\begin{funcdesc}{debug_src}{src\optional{, pm}\optional{, globs}}
Debug the doctests in a string.
This is like function \function{debug()} above, except that
a string containing doctest examples is specified directly, via
the \var{src} argument.
Optional argument \var{pm} has the same meaning as in function
\function{debug()} above.
Optional argument \var{globs} gives a dictionary to use as both
local and global execution context. If not specified, or \code{None},
an empty dictionary is used. If specified, a shallow copy of the
dictionary is used.
\versionadded{2.4}
\end{funcdesc}
The \class{DebugRunner} class, and the special exceptions it may raise,
are of most interest to testing framework authors, and will only be
sketched here. See the source code, and especially \class{DebugRunner}'s
docstring (which is a doctest!) for more details:
\begin{classdesc}{DebugRunner}{\optional{checker}\optional{, \begin{classdesc}{DebugRunner}{\optional{checker}\optional{,
verbose}\optional{, optionflags}} verbose}\optional{, optionflags}}
@ -1591,6 +1731,9 @@ Doctest provides three mechanisms for debugging doctest examples:
section~\ref{doctest-advanced-api}. section~\ref{doctest-advanced-api}.
\end{classdesc} \end{classdesc}
There are two exceptions that may be raised by \class{DebugRunner}
instances:
\begin{excclassdesc}{DocTestFailure}{test, example, got} \begin{excclassdesc}{DocTestFailure}{test, example, got}
An exception thrown by \class{DocTestRunner} to signal that a An exception thrown by \class{DocTestRunner} to signal that a
doctest example's actual output did not match its expected output. doctest example's actual output did not match its expected output.
@ -1608,20 +1751,7 @@ Doctest provides three mechanisms for debugging doctest examples:
The example's actual output. The example's actual output.
\end{memberdesc} \end{memberdesc}
\begin{funcdesc}{testsource}{module, name} \begin{excclassdesc}{UnexpectedException}{test, example, exc_info}
Extract the doctest examples from a docstring.
Provide the \var{module} (or dotted name of the module) containing the
tests to be extracted and the \var{name} (within the module) of the object
with the docstring containing the tests to be extracted.
The doctest examples are returned as a string containing Python
code. The expected output blocks in the examples are converted
to Python comments.
\versionadded{2.3}
\end{funcdesc}
\begin{excclassdesc}{UnexpectedException}{test, example, got}
An exception thrown by \class{DocTestRunner} to signal that a An exception thrown by \class{DocTestRunner} to signal that a
doctest example raised an unexpected exception. The constructor doctest example raised an unexpected exception. The constructor
arguments are used to initialize the member variables of the same arguments are used to initialize the member variables of the same