Skip to content Skip to sidebar Skip to footer

Doctests: How To Suppress/ignore Output?

The doctest of the following (nonsense) Python module fails: ''' >>> L = [] >>> if True: ... append_to(L) # XXX >>> L [1] ''' def append_to(L): L

Solution 1:

rewrite: This actually does work now; I realized that the "doctest" I had written earlier was actually not being parsed as the module docstring, so the test wasn't passing: it was just not being run.

I made sure to double-check this one.

__doc__ = """
>>> L = []
>>> if True:
...    append_to(L) # doctest: +IGNORE_RESULT
>>> L
[1]
""".replace('+IGNORE_RESULT', '+ELLIPSIS\n<...>')

defappend_to(L):
    L.append(1)
    classA(object):
        passreturn A()

I'm not sure if this qualifies as more readable or not. Note that there's nothing special about <...>: it will only work if the actual return value has that form, as it does in this case (i.e. it's <module.A object at 0x...>). The ELLIPSIS option makes ... "match any substring in the actual output" ¹. So I don't think there's a way to get it to match the entirety of the output.

update: To do this the "proper" way, it looks like you'd want to call doctest.register_optionflag('IGNORE_RESULT'), subclass doctest.OptionChecker, and arrange for an instance of that subclass to be used by the doctest. Presumably this means that running your doctest via $ python -m doctest your_module.py is not an option.

Solution 2:

I ended up in this question because I need the +IGNORE_RESULT behavior but for running doc tests on sphinx documentation. The replace answer posted by @intuited does not work in that case and there was no code for the mentioned "proper" solution. Therefore I post what I ended up with.

As a direct answer to the question the solution would be:

__doc__ = """
>>> L = []
>>> if True:
...    append_to(L) # doctest: +IGNORE_RESULT
>>> L
[1]
"""defappend_to(L):
    L.append(1)
    classA(object):
        passreturn A()

if __name__ == "__main__":
    import doctest

    IGNORE_RESULT = doctest.register_optionflag('IGNORE_RESULT')

    OutputChecker = doctest.OutputChecker
    classCustomOutputChecker(OutputChecker):
        defcheck_output(self, want, got, optionflags):
            if IGNORE_RESULT & optionflags:
                returnTruereturn OutputChecker.check_output(self, want, got, optionflags)

    doctest.OutputChecker = CustomOutputChecker
    doctest.testmod()

For my particular need of doc testing sphinx documentation add to the conf.py file:

import doctest

IGNORE_RESULT = doctest.register_optionflag('IGNORE_RESULT')

OutputChecker = doctest.OutputChecker
classCustomOutputChecker(OutputChecker):
    defcheck_output(self, want, got, optionflags):
        if IGNORE_RESULT & optionflags:
            returnTruereturn OutputChecker.check_output(self, want, got, optionflags)

doctest.OutputChecker = CustomOutputChecker

Then test with a command such as:

sphinx-build -M doctest source_dir build_dir source_dir/file.rst

Solution 3:

Please try to give fully self-contained, runnable code; even when you're demonstrating a problem, the code should run on its own to reproduce the problem, so solutions can copy the code directly for demonstrating the answer.

I don't know of a clean solution to this, and I've hit it before; it seems a side-effect of the fuzzy (more bluntly: sloppy) test definitions doctests provide. A workaround is to remember that you can define functions within doctests, so you can contain a whole test as a single function rather than as its individual statements.

defappend_to(l):
    """
    >>> L = []
    >>> def test():
    ...     if True:
    ...         append_to(L) # XXX
    >>> test()
    >>> L
    [1]

    >>> def test():
    ...     L = []
    ...     if True:
    ...         append_to(L) # XXX
    ...     return L
    >>> test()
    [1]

    """
    l.append(1)
    returnobject()

if __name__ == "__main__":
    import doctest
    doctest.testmod()

Post a Comment for "Doctests: How To Suppress/ignore Output?"