I have a particular Doctest that is working correctly in python 2.7 but not in python 3.4.
"""
Trying to build a cyclic network (should fail):
>>> buildCyclicNetwork(False)
Traceback (most recent call last):
...
NetworkConstructionException: Loop in network graph.
"""
if __name__ == "__main__":
runModuleTestSuite(__import__('__main__'))
The testsuite is compiled here, with the options
def runModuleTestSuite(module):
"""Runs a test suite for all local tests."""
suite = TestSuite([TestLoader().loadTestsFromModule(module)])
# Add local doctests
optionflags = ELLIPSIS | NORMALIZE_WHITESPACE | REPORT_ONLY_FIRST_FAILURE
try:
suite.addTest(DocTestSuite(module, optionflags=optionflags))
except ValueError:
# No tests have been found in that module.
pass
TextTestRunner().run(suite)
I've tried to use # doctest: +ELLIPSIS in the docstring itself, but this does not solve anything. I'm puzzled as to why this works under 2.x but not 3.x. The particular problem here is an ellipses eliding the path in the traceback. When the test fails it outputs:
Expected:
Traceback (most recent call last):
...
NetworkConstructionException: Loop in network graph.
Got:
Traceback (most recent call last):
File "/usr......complete trace path"
networks.network.NetworkConstructionException: Loop in network graph.
This is covered in the documentation. Although the ELLIPSIS
docs don't directly explain it, the next section on IGNORE_EXCEPTION_DETAIL
says:
It will also ignore the module name used in Python 3 doctest reports. Hence both of these variations will work with the flag specified, regardless of whether the test is run under Python 2.7 or Python 3.2 (or later versions) …
Note that
ELLIPSIS
can also be used to ignore the details of the exception message, but such a test may still fail based on whether or not the module details are printed as part of the exception name. UsingIGNORE_EXCEPTION_DETAIL
and the details from Python 2.3 is also the only clear way to write a doctest that doesn’t care about the exception detail yet continues to pass under Python 2.3 or earlier (those releases do not support doctest directives and ignore them as irrelevant comments).
In other words, the problem is that ...
will not skip over the networks.network.
part that 3.x tracebacks print out, this is a known limitation in doctest
, and there's no way around it short of using IGNORE_EXCEPTION_DETAIL
instead.
If all you want to check is the type, this is actually better—it's simpler, more readable, and harder to get wrong. But what if you want to check the exception value, not just the types? There are hacky workarounds to do that (e.g., replace builtins.isinstance
with a function that calls an __instancehook__
so you can define a class that's a superclass of only if the value matches), but I don't think those are worth doing. If you really need to distinguish a specific exception, it should probably be a distinct subtype in the first place.