Re: [Python-Dev] PEP 310 and exceptions
Shane Hathaway wrote: Nick Coghlan wrote: 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. While we're on the subject of block handler method names, do the method names need four underscores? 'enter' and 'exit' look better than '__enter__' and '__exit__'. It's traditional for slots (or pseudo-slots) to have magic method names. It implies that the methods are expected to be called implicitly via special syntax or builtin functions, rather than explicitly in a normal method call. The only exception I can think of is the 'next' method of the iterator protocol. That method is often called explicitly, so the exception makes sense. For resources, there doesn't seem to be any real reason to call the methods directly - the calls will generally be hidden behind the 'with' block syntax. Hence, magic methods. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
Toby Dickenson [EMAIL PROTECTED] wrote: On Sunday 24 April 2005 07:42, Nick Coghlan wrote: Shane Hathaway wrote: While we're on the subject of block handler method names, do the method names need four underscores? 'enter' and 'exit' look better than '__enter__' and '__exit__'. I quite like .acquire() and .release(). There are plenty of classes (and not just in the threading module) which already have methods with those names that could controlled by a 'with'. Those names also make the most sense in the C++ 'resource acquisition' model. Perhaps, but names for the equivalent of acquire resource and release resource are not consistant accross modules. Also, re-read Nick Coghlan's email with message id [EMAIL PROTECTED]. - Josiah ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
[EMAIL PROTECTED] (holger krekel) wrote: basically translates to: if hasattr(x, '__enter__'): x.__enter__() try: ... except: if hasattr(x, '__except__'): x.__except__(...) else: x.__exit__() else: x.__exit__() Nope... def foo(): ... try: ... print 1 ... return ... except: ... print 2 ... else: ... print 3 ... foo() 1 - Josiah ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
On Apr 22, 2005, at 16:51, holger krekel wrote: Moreover, i think that there are more than the transactional use cases mentioned in the PEP. For example, a handler may want to log exceptions to some tracing utility or it may want to swallow certain exceptions when its block does IO operations that are ok to fail. I entirely agree! In fact, I was discussing this very issue recently with colleagues at Google, most of them well acquainted with Python but not all of them Python enthusiasts, and I was surprised to see unanimity on how PEP 310 *with* __except__ would be a huge step up in usefulness wrt the simple __enter__/__exit__ model, which is roughly equivalent in power to the C++ approach (destructors of auto variables) whose absence from Python and Java some people were bemoaning (which is how the whole discussion got started...). The use cases appear to be aleph-0 or more...;-). Essentially, think of it of encapsulating into reusable forms many common patterns of try/except use, much like iterators/generators can encapsulate looping and recursive constructs, and a new vista of uses open up... Imagine that in two or three places in your code you see something like... try: ...different blocks here... except FooError, foo: # some FooError cases need whizbang resetting before they propagate if foo.wobble FOOBAR_RESET_THRESHOLD: whizbang.reset_all() raise With PEP 310 and __except__, this would become: with foohandler: ...whatever block.. in each and every otherwise-duplicated-logic case... now THAT is progress!!! IOW, +1 ... ! Alex ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
On Fri, Apr 22, 2005 at 19:03 -0700, Josiah Carlson wrote: [EMAIL PROTECTED] (holger krekel) wrote: basically translates to: if hasattr(x, '__enter__'): x.__enter__() try: ... except: if hasattr(x, '__except__'): x.__except__(...) else: x.__exit__() else: x.__exit__() Nope... def foo(): ... try: ... print 1 ... return ... except: ... print 2 ... else: ... print 3 ... foo() 1 doh! of course, you are right. So it indeeds better translates to a nested try-finally/try-except when transformed to python code. Nick Coghlan points at the correct ideas below in this thread. At the time i was implementing things by modifying ceval.c rather than by just a compiling addition, i have to admit. cheers, holger ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
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. (I'm a bit sensitive to that right now; this week I wasted an hour because I didn't understand exceptions as well as I thought I did, although it was related more to the precise mechanics of raising and catching exceptions. Perhaps I'll submit a doc bug; I didn't find this explained in _Learning Python_ or Nutshell...) -- Aahz ([EMAIL PROTECTED]) * http://www.pythoncraft.com/ It's 106 miles to Chicago. We have a full tank of gas, a half-pack of cigarettes, it's dark, and we're wearing sunglasses. Hit it. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
Nick Coghlan wrote: Alternately, PEP 310 could be defined as equivalent to: if hasattr(x, '__enter__'): x.__enter__() try: try: ... except: if hasattr(x, '__except__'): x.__except__(*sys.exc_info()) else: raise finally: x.__exit__() 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] A possible tweak to this line would be to have it swallow the exception by default (by removing the conditional reraise). I'd prefer to make the silencing of the exception explicit, by returning 'True' from the exception handling, and have 'falling off the end' of the exception handler cause the exception to propagate. Whichever way that point goes, this definition would allow PEP 310 to handle Alex's example of factoring out standardised exception handling, as well as the original use case of resource cleanup, and the transaction handling: class transaction(object): def __enter__(self): begin_transaction() def __except__(self, *exc_info): abort_transaction() def __else__(self): commit_transaction() Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
At 01:41 PM 4/23/05 +1000, Nick Coghlan wrote: Whichever way that point goes, this definition would allow PEP 310 to handle Alex's example of factoring out standardised exception handling, as well as the original use case of resource cleanup, and the transaction handling: class transaction(object): def __enter__(self): begin_transaction() def __except__(self, *exc_info): abort_transaction() def __else__(self): commit_transaction() I'd like to suggest '__success__' in place of '__else__' and '__before__'/'__after__' instead of '__enter__'/'__exit__', if you do take this approach, so that what they do is a bit more obvious. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
Nick Coghlan [EMAIL PROTECTED] writes: holger krekel wrote: Moreover, i think that there are more than the transactional use cases mentioned in the PEP. For example, a handler may want to log exceptions to some tracing utility or it may want to swallow certain exceptions when its block does IO operations that are ok to fail. With the current PEP 310 definition, these can be manually handled using sys.exc_info() in the __exit__ method. With the proposed implementation of PEP 310 rev. 1.5 it wouldn't work. sys.exc_info returns a tuple of Nones unless an except: clause has been entered. Either sys.exc_info() would have to be changed to always return exception information after an exception has been raised or the implementation would have to be changed to do the equivalent of e.g. if hasattr(var, __enter__): var.__enter__() try: try: suite except: pass finally: var.__exit__() An empty except: suite suffices. In C that's equivalent to a call to PyErr_NormalizeException AFAICT. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://skencil.org/ Thuban http://thuban.intevation.org/ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
Bernhard Herzog wrote: With the proposed implementation of PEP 310 rev. 1.5 it wouldn't work. sys.exc_info returns a tuple of Nones unless an except: clause has been entered. Either sys.exc_info() would have to be changed to always return exception information after an exception has been raised or the implementation would have to be changed to do the equivalent of e.g. Interesting. Although the 'null' except block should probably be a bare 'raise', rather than a 'pass': Py try: ... try: ... raise TypeError(I'm an error!) ... except: ... raise ... finally: ... print sys.exc_info() ... (class exceptions.TypeError at 0x009745A0, exceptions.TypeError instance at 0 x009E7238, traceback object at 0x009E72B0) Traceback (most recent call last): File stdin, line 3, in ? TypeError: I'm an error! All the more reason to consider switching to a nested try/finally + try/except/else definition for 'with' blocks, I guess. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 310 and exceptions
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 | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com