On Thu, Sep 30, 2021 at 07:41:47AM -0300, Soni L. wrote:

> You misnderstand exception hygiene. It isn't about "do the least stuff
> in try blocks", but about "don't shadow unrelated exceptions into your
> public API".

I disagree with that. I don't think that "exception hygiene" is a common 
term in software development (at least googling doesn't find many 
examples of the term) so it is not like there is a canonical definition 
beyond "clean use of exceptions", which is going to be at least partly 
subjective.

I think that doing the least amount of work necessary inside a try block 
is a large part of exception hygiene. Likewise catching the smallest 
subset of exceptions that you know how to meaningfully handle.

Large try blocks with a bunch of stuff inside them is an obvious Code 
Smell in the sense that Joel Spolsky talks about:

https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/

As soon as I see a big block of code inside a try block, it smells a bit 
fishy and I know that I need to think *really carefully* about the 
possibility that maybe it is catching too many exceptions.

    try:
        n = len(item)
        # followed by thirty more lines of code...
    except TypeError:
        print('item is not a sequence')
        fallback()

I have to think really hard, am I *really sure* that none of those other 
thirty lines can raise TypeError, which will then be wrongly diagnosed 
and wrongly handled? That's a code smell. It's not a clean use of 
exceptions. It is dirty, not clean. It is *unhygienic*.


> For example, generators don't allow you to manually raise StopIteration
> anymore:
[...]
> This is a (limited) form of exception hygiene. Can we generalize it?

Sure. See the "exception guard" recipe I posted. If you go to the 
recipe, it links to some discussions.


> This effectively means all generators *are*
> wrapped in a try/except, so your point about "too much stuff inside a
> try block" goes directly against accepted practice and even existing
> python features as they're implemented.

StopIteration is very special. It doesn't even inherit from Exception. 
It is used directly for flow control by the interpreter.

(Which goes against accepted practice in other languages:

https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why

One might ask, is Python doing it wrong, is everyone else doing it 
wrong, or are we asking the wrong questions? By I digress.)

We might take the point of view that StopIteration is reserved for use 
by iterators, and that the interpreter reserves the use to treat *any* 
use of StopIteration in any other context as undefined behaviour, and 
that we ought to be grateful that the interpreter merely converts it to 
a RuntimeError instead of making demons fly out of your nose.

http://catb.org/jargon/html/N/nasal-demons.html

So I don't think we should be too gung-ho about generalising from 
StopIteration (a specific exception used by the interpreter for flow 
control) to arbitrary exceptions which represent error conditions.

(More to follow.)


-- 
Steve
_______________________________________________
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/FHVI34KM5BA7OI3AQKWRX7JBNBRPHE5W/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to