Re: [Python-Dev] PEP 310 and exceptions

2005-04-24 Thread Nick Coghlan
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

2005-04-24 Thread Josiah Carlson

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

2005-04-23 Thread Josiah Carlson

[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

2005-04-23 Thread Alex Martelli
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

2005-04-23 Thread holger krekel
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

2005-04-23 Thread Aahz
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

2005-04-23 Thread Nick Coghlan
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

2005-04-23 Thread Phillip J. Eby
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

2005-04-23 Thread Bernhard Herzog
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

2005-04-23 Thread Nick Coghlan
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

2005-04-23 Thread Nick Coghlan
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