doctest, sys.stderr, SystemExit and unused return values

Steven Bethard steven.bethard at gmail.com
Sat Jul 1 18:20:51 EDT 2006


I have an optparse-like module and though I have a full unittest-style 
suite of tests for it, I'd also like to be able to run doctest on the 
documentation to make sure my examples all work.  However, I see that 
doctest (1) doesn't capture anything from sys.stderr, and (2) unlike the 
normal interpreter, generates a traceback for SystemExit.

Here's what some of my tests look like and the doctest output I get::

     ========== in my documentation ==========
     >>> parser.print_help()
     usage: PROG [-h] [-w W] [-x X [X ...]] [y] [z [z ...]]

     optional arguments:
       -h, --help    show this help message and exit
       -w W          w help
       -x X [X ...]  x help

     positional arguments:
       y             y help
       z             z help

     ========== the doctest output ==========
     Failed example:
         parser.print_help()
     Expected:
         usage: PROG [-h] [-w W] [-x X [X ...]] [y] [z [z ...]]


     ========== in my documentation ==========
     >>> parser.parse_args('xyz --b 42'.split())
     usage: PROG xyz [-h] [--x XXX] [-y] z
     PROG xyz: error: no such option: --b

     ========== the doctest output ==========
     Failed example:
         parser.parse_args('xyz --b 42'.split())
     Exception raised:
         Traceback (most recent call last):
             ...
         SystemExit: 2

Just like with optparse, calling ``print_help()`` and ``parse_args()`` 
prints to sys.stderr, and ``parse_args()`` raises SystemExit when it 
encounters an error.

Is there a way to get these tests to pass?


On a related note, my examples currently use a lot of ``_ =`` because, 
like optparse, I quite frequently don't care about the return value of 
calls to add arguments, e.g.::

     >>> parser = argparse.ArgumentParser(prog='PROG')
     >>> _ = parser.add_optional('--foo', help='foo help')
     >>> _ = parser.add_positional('bar', help='bar help')
     >>> values = parser.parse_args('--foo spam badger'.split())
     >>> values.foo
     'spam'
     >>> values.bar
     'badger'

Is there any way to avoid having to write the ``_ =`` without getting an 
error like::

     Failed example:
         parser.add_optional('--foo', help='foo help')
     Expected nothing
     Got:
         Optional('--foo', dest='foo', action=None, ...

I don't want to include the whole Optional repr() string because it's 
long and it distracts from the point of the example.

STeVe




More information about the Python-list mailing list