On 31Dec2015 12:26, Steven D'Aprano <st...@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 <c...@zip.com.au>
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to