Executive summary:

1.  Don't distinguish exceptions if it won't make a difference to how
    you handle them (Andrew also makes this point, and I think it's
    implicit in MAL's post about exception vs. the reason as well).

2.  Usefully introducing more fine-grained exceptions requires that
    *other* people use them when *you* want them to.  Both
    introspection into my own behavior and the complaint about "shitty
    corporate systems" suggests that's a "Not Gonna Happen" for all of
    the proposed exceptions (I think this is Steven d'Aprano's point,
    too).

Ram Rachum writes:

 > If I do this:

 >     >>> x, y = range(3)

 > It would be nice if the operation above raised UnpackingOverflowError,
 > which will be a subclass of UnpackingError, along with
 > UnpackingUnderflowError.  UnpackingError can be a subclass of ValueError,
 > for backward compatibility.

It's not a matter of backward compatibility (unless the Exception
class to raise was chosen incorrectly in the first place).  The point
of distinguishing among Exceptions is that you want to handle them
differently.  But there's not much you can do with a ValueError or
TypeError, because Python implements the "termination model" of
exception handling.  That is, the program stops what it's doing, and
throws away all the work done to that point, including the
continuation.  It's generally going to be somewhere between
impractical and impossible to determine how to fix the input to the
computation and restart it.  You either need to fix the program and
run it on the same inputs, or go on to the next input.  Even if you
raise a specific subclass, I'm probably going to handle it the same as
any other ValueError.

On the other hand, there are a plethora of environment errors, such as
3 suberrors of ConnectionError, at least 6 different errors related to
opening filesystem objects, and so on.  Why?  Because there are well-
known, common strategies allowing programs to recover from such
errors, and programs that catch them are prepared for them with
specific handlers for each such exception.

I admit I don't recall offhand ever making a pragmatic distinction
between TypeError and ValueError myself, except that ValueErrors are
often validation errors (eg, a typo), while TypeErrors are invariably
a logic error in my experience.  But that's a difference in how I
respond, not in how my program does.  So the principle "don't make
distinctions without a difference" isn't followed 100% (at least in
terms of my personal pragmatics).  But nothing's perfect.  The best we
can do is to not make things worse.

 > Similarly, if I did this:
 > 
 >     >>> def f(x, y): return x + y
 >     >>> f(1)
 > 
 > I would get a TypeError. Would be a lot cooler if I got
 > MissingArgumentsError, which would be a subclass of SignatureError, which
 > would be a subclass of TypeError.

Cool, maybe, but the relevant question for distinguishing a new
exception is how would your *program* respond differently to a
different subclass of SignatureError or TypeError?

 > There are 2 reasons I want this:
 > 
 > 1. When I'm writing a try..except clause, I want to catch a specific
 > exception like MissingArgumentsError rather than ValueError or TypeError.
 > They're too ubiquitous. I don't want some other unexpected failure
 > producing the same ValueError and triggering my except clause.

If you're writing the code that raises the Exception, I see no problem
except your willingness to define the appropriate subclasses of
ValueError.  :-)

For SomebodyElse'sCode, here's the rub:

 > 2. When I get an error, especially from some shitty corporate system that
 > truncates the traceback, I want to get as many hints as possible about what
 > went wrong.

Why do you think "shitty corporate systems" (or quick hacks on PyPI)
are going to use fine-grained exceptions (a) correctly (b) at all?
(This is a real question, despite my obvious priors as to the answer.)

 > It's true that today, most Python exceptions have good text in their
 > message, like "TypeError: f() missing 1 required positional argument: 'y'".
 > But that isn't guaranteed everywhere, and specific exception types could
 > help.

I don't see much chance of that pragmatically.  I write a lot of code
that just raises RuntimeError because I don't feel like looking up and
figuring out the appropriate subclass.  Some of that code makes it
into production, to my later chagrin.  (Mostly not: "replace all
RuntimeErrors with something appropriate" is on my personal review
checklist. :-)  IMO, if developers aren't willing to write a descriptive
message, the effort to choose a specific exception appropriately is
unlikely to be worth it to them.  That effort is at best strictly
convex, and quite possibly exponential, in the number of Exceptions
defined.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/EFGFSE2V6BRZOPHJ4IK2IBTSCXSOL7MS/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to