[Python-Dev] Exceptions doctest Re: Request for review
tim.peters at gmail.com
Thu Apr 13 17:08:03 CEST 2006
>> doctest strives to be magic-free WYSIWYG. If someone _intends_
>> the module name to be optional in a doctest, they should explicitly
>> use doctest's ELLIPSIS option.
> There's already a little bit of magic in the way doctest handles exceptions. I
> always use doctest.IGNORE_EXCEPTION_DETAIL so that everything after the first
> colon on the last line gets ignored when matching exceptions.
Explicitly specifiying IGNORE_EXCEPTION_DETAIL isn't "magic" -- it's
explicitly asking for something.
> That allows me to include the text of the exception in the documentation so
> its clear what the associated problem is, without worrying about spurious
> failures due to variations in the exact wording of the error message.
Which is the documented purpose of IGNORE_EXCEPTION_DETAIL, for tests
that want it. I rarely use it myself, but not never ;-)
> Using an ellipsis instead would get essentially the same effect from a test
> point of view, but would result in less effective documentation. Given that
> the option exists, I assume I'm not the only who thinks that way.
The reason ELLIPSIS isn't always suitable for this purpose is
explained in the IGNORE_EXCEPTION_DETAIL docs:
Note that a similar effect can be obtained using ELLIPSIS, and
IGNORE_EXCEPTION_DETAIL may go away when Python releases prior to 2.4
become uninteresting. Until then, IGNORE_EXCEPTION_DETAIL is the only
clear way to write a doctest that doesn't care about the exception
continues to pass under Python releases prior to 2.4 (doctest
to be comments to them). For example, [& see the docs for the example]
> To get back to the original question of ignoring module names, I wonder if
> doctext should actually try to be a bit cleverer about the way it matches
> exceptions when the ignore exception detail flag is in effect.
> At the moment, documenting something as raising ZeroDivisionError in a
> doctest, but then actually raising a differently named subclass (such as
> decimal.DivisionByZero) in the code will result in a failed test.
Perfect: the doctest is lying in such a case, and should fail.
WYSIWYG rules for doctest.
> IMO, this is a spurious failure if I've told the doctest engine that I don't
> care about the details of exceptions raised
This is a doc problem that's my fault: you're reading "exception
detail" as a vague catch-all description, which is reasonable enough.
I intended to use it as a technical term, referring specifically to
str() of the exception object (the thing bound to an `except`
statement's second parameter). For example, as in (among other
except Exception, detail:
Maybe I'm hallucinating, but I believe that was standard usage of the
term way back when. If so, terminology probably changed when
exceptions no longer needed to be strings, and I didn't notice.
Regardless, the doctest docs are almost <0.5 wink> clear enough about
what it intends here.
> - there's nothing wrong with the documentation, as the following relationship holds:
> Py> issubclass(decimal.DivisionByZero, ZeroDivisionError)
> The fact that what the call raises is technically an instance of a subclass
> rather than of the listed class is really an implementation detail, just like
> the text in the associated error message. The important point is that an
> except clause covering the documented exception type will catch the raised
> The doctest machinery has access to both the expected exception name, the
> actual exception raised, and the dictionary used to execute the test, so
> something like "issubclass(exc_type, eval(expected_exc_name, test_globs))"
> should do the trick (with a bit of work to extract the expected exception
> name, naturally).
Sorry, but it's horridly un-doctest-like to make inferences by magic.
If you want to add an explicit ACCEPT_EXCEPTION_SUBCLASS doctest
option, that's a different story. I would question the need, since
I've never got close to needing it, and never heard anyone else bring
it up. Is this something that happens to you often enough to be an
irritation, or is it just that your brain tells you it's a cool idea?
One reason I have to ask is that I'm pretty sure the example you gave
is one that never bit you in real life.
More information about the Python-Dev