[Python-Dev] PEP 310 and exceptions

Nick Coghlan ncoghlan at gmail.com
Sun Apr 24 03:58:45 CEST 2005


Aahz wrote:
> On Sat, Apr 23, 2005, Nick Coghlan wrote:
> 
>>In light of Alex's comments, I'd actually like to suggest the below as a 
>>potential new definition for PEP 310 (making __exit__ optional, and adding 
>>an __else__ handler):
>>
>>    if hasattr(x, '__enter__'):
>>        x.__enter__()
>>    try:
>>        try:
>>            # Contents of 'with' block
>>        except:
>>            if hasattr(x, '__except__'):
>>                if not x.__except__(*sys.exc_info()): # [1]
>>                    raise
>>            else:
>>                raise
>>        else:
>>            if hasattr(x, '__else__'):
>>                x.__else__()
>>    finally:
>>        if hasattr(x, '__exit__'):
>>            x.__exit__()
> 
> 
> +1, but prior to reading this post I was thinking along similar lines
> with your __exit__ named __finally__ and your __else__ named __exit__.
> My reasoning for that is that most of the time, people want their exit
> condition aborted if an exception is raised; having the "normal" exit
> routine called __else__ would be confusing except to people who do lots
> of exception handling.

In the original motivating use cases (file handles, synchronisation objects), 
the resource release is desired unconditionally. The aim is to achieve something 
similar to C++ scope-delimited objects (which release their resources 
unconditionally as the scope is exited). This parallel is also probably the 
source of the names of the two basic functions ('enter'ing the contained block, 
'exit'ing the contained block).

So, I think try/finally is the right semantics for the basic __enter__/__exit__ 
use case (consider that PEP 310 is seen as possibly worthwhile with *only* these 
semantics!).

For error logging type use cases, only the exception handling is required. The 
issue of a 'no exception raised' handler only comes up for cases like 
transactions, where the commit operation is conditional on no exception being 
triggered. I understand you agree that, for those cases, the best spot to call 
the handler is an else clause on the inner try/except block. That way, it is 
skipped by default if an exception goes off, but the exception handling method 
can still invoke the method directly if desired (e.g. an exception is determined 
to be 'harmless'.

However, I do agree with you that the use of '__else__' as a name is exposing 
too much of the underlying implementation (i.e. you need to understand the 
implementation for the name to make sense). I think renaming '__exit_' to 
'__finally__' would be a similar error, though.

Which means finding a different name for '__else__'. Two possibilities that 
occur to me are '__ok__' or '__no_except__'. The latter makes a fair amount of 
sense, since I can't think of a way to refer to the thing other than as a 'no 
exception' handler.

Cheers,
Nick.

P.S. I'm ignoring my housemate's suggestion of '__accept__' for the no-exception 
handler :)

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net


More information about the Python-Dev mailing list