[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