raise None
Cameron Simpson
cs at zip.com.au
Wed Dec 30 23:03:20 EST 2015
On 31Dec2015 12:26, Steven D'Aprano <steve at pearwood.info> wrote:
>On Thu, 31 Dec 2015 11:38 am, Chris Angelico wrote:
>>> [... functions calling common _validate function ...]
>>> But when the argument checking fails, the traceback shows the error
>>> occurring in _validate, not eggs or spam. (Naturally, since that is where
>>> the exception is raised.) That makes the traceback more confusing than it
>>> need be.
>>
>> If the validation really is the same in all of them, then is it a
>> problem to see the validation function in the traceback? Its purpose
>> isn't simply "raise an exception", but "validate a specific set of
>> inputs". That sounds like a perfectly reasonable traceback line to me
>> (imagine if your validation function has a bug).
>
>Right -- that's *exactly* why it is harmful that the _validate function
>shows up in the traceback.
I think I'm still disagreeing, but only on this point of distinguishing
_validate bug exceptions from _validate test failures.
>If _validate itself has a bug, then it will raise, and you will see the
>traceback:
>
>Traceback (most recent call last):
> File "spam", line 19, in this
> File "spam", line 29, in that
> File "spam", line 39, in other
> File "spam", line 5, in _validate
>ThingyError: ...
>
>which tells you that _validate raised an exception and therefore has a bug.
Ok....
>Whereas if _validate does what it is supposed to do, and is working
>correctly, you will see:
>
>Traceback (most recent call last):
> File "spam", line 19, in this
> File "spam", line 29, in that
> File "spam", line 39, in other
> File "spam", line 5, in _validate
>ThingyError: ...
>
>and the reader has to understand the internal workings of _validate
>sufficiently to infer that this exception is not a bug in _validate but an
>expected failure mode of other when you pass a bad argument.
Would it not be useful then to name the including function in the exception
text?
>In the case where _validate *returns* the exception instead of raising it,
>and the calling function (in this case other) raises, you see this in the
>case of a bug in _validate:
>
>Traceback (most recent call last):
> File "spam", line 19, in this
> File "spam", line 29, in that
> File "spam", line 39, in other
> File "spam", line 5, in _validate
>ThingyError: ...
>
>and this is the case of a bad argument to other:
>
>Traceback (most recent call last):
> File "spam", line 19, in this
> File "spam", line 29, in that
> File "spam", line 39, in other
>ThingyError: ...
I confess that when I want to check several things I would like to return
several failure indications. So thing on that line, how about this:
for blam in _validate(a, b):
raise blam
which leaves you open to gatheroing them all up instead of aborting on the
first complaint.
>I think this is a win for debuggability. (Is that a word?) But it's a bit
>annoying to do it today, since you have to save the return result and
>explicitly compare it to None. If "raise None" was a no-op, it would feel
>more natural to just say raise _validate() and trust that if _validate
>falls out the end and returns None, the raise will be a no-op.
This is a nice idea though. Succinct and expressive, though people would have
to learn that:
raise foo()
does not unconditionally abort at this point.
Cheers,
Cameron Simpson <cs at zip.com.au>
More information about the Python-list
mailing list