[Python-checkins] python/nondist/peps pep-0343.txt,1.1,1.2

gvanrossum@users.sourceforge.net gvanrossum at users.sourceforge.net
Sat May 14 04:02:42 CEST 2005


Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25715
Modified Files:
	pep-0343.txt 
Log Message:
Don't be wishy-washy about the call to __exit__().
Fix the redirecting_stdout() example (remove the try/finally).
Index: pep-0343.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0343.txt,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- pep-0343.txt	14 May 2005 00:08:20 -0000	1.1
+++ pep-0343.txt	14 May 2005 02:02:40 -0000	1.2
@@ -46,23 +46,28 @@
 The translation of the above statement is:
 
 abc = EXPR
+ exc = () # Or (None, None, None) ?
 try:
- VAR = abc.__enter__()
- BLOCK
+ try:
+ VAR = abc.__enter__()
+ BLOCK
+ except:
+ exc = sys.exc_info()
+		raise
 finally:
- abc.__exit__(*sys.exc_info()) # XXX See below
+ abc.__exit__(exc)
 
 If the "as VAR" part of the syntax is omitted, the "VAR =" part of
 the translation is omitted (but abc.__enter__() is still called).
 
- The call to abc.__exit__() is only approximated as written. The
- actual calling convention is: If the finally-suite was reached
- through normal completion of BLOCK or through a "non-local goto"
- (a break, continue or return statement in BLOCK), abc.__exit__()
- is called without arguments (or perhaps with three None
- arguments). If the finally-suite was reached through an exception
- raised in BLOCK, abc.__exit__() is called with three arguments
- representing the exception type, value, and traceback.
+ The calling convention for abc.__exit__() is: as follows. If the
+ finally-suite was reached through normal completion of BLOCK or
+ through a "non-local goto" (a break, continue or return statement
+ in BLOCK), abc.__exit__() is called without arguments (or perhaps
+ with three None arguments?). If the finally-suite was reached
+ through an exception raised in BLOCK, abc.__exit__() is called
+ with three arguments representing the exception type, value, and
+ traceback.
 
 Optional Generator Decorator
 
@@ -70,41 +75,41 @@
 a generator that yields exactly once to control a do-statement.
 Here's a sketch of such a decorator:
 
-	class Wrapper(object):
-	 def __init__(self, gen):
-	 self.gen = gen
-	 self.state = "initial"
-	 def __enter__(self):
-	 assert self.state == "initial"
-	 self.state = "entered"
-	 try:
-		 return self.gen.next()
-	 except StopIteration:
-		 self.state = "error"
-		 raise RuntimeError("template generator didn't yield")
-	 def __exit__(self, *args):
-	 assert self.state == "entered"
-	 self.state = "exited"
-	 try:
-		 self.gen.next()
-	 except StopIteration:
-		 return
-	 else:
-		 self.state = "error"
-		 raise RuntimeError("template generator didn't stop")
+ class Wrapper(object):
+ def __init__(self, gen):
+ self.gen = gen
+ self.state = "initial"
+ def __enter__(self):
+ assert self.state == "initial"
+ self.state = "entered"
+ try:
+ return self.gen.next()
+ except StopIteration:
+ self.state = "error"
+ raise RuntimeError("template generator didn't yield")
+ def __exit__(self, *args):
+ assert self.state == "entered"
+ self.state = "exited"
+ try:
+ self.gen.next()
+ except StopIteration:
+ return
+ else:
+ self.state = "error"
+ raise RuntimeError("template generator didn't stop")
 
-	def do_template(func):
-	 def helper(*args, **kwds):
-	 return Wrapper(func(*args, **kwds))
-	 return helper
+ def do_template(func):
+ def helper(*args, **kwds):
+ return Wrapper(func(*args, **kwds))
+ return helper
 
 This decorator could be used as follows:
 
-	@do_template
-	def opening(filename):
-	 f = open(filename) # IOError here is untouched by Wrapper
-	 yield f
-	 f.close() # Ditto for errors here (however unlikely)
+ @do_template
+ def opening(filename):
+ f = open(filename) # IOError here is untouched by Wrapper
+ yield f
+ f.close() # Ditto for errors here (however unlikely)
 
 A robust implementation of such a decorator should be made part of
 the standard library.
@@ -151,14 +156,14 @@
 
 class transactional:
 def __init__(self, db):
-	 self.db = db
+ self.db = db
 def __enter__(self):
 pass
-	 def __exit__(self, *args):
-	 if args and args[0] is not None:
-		 self.db.rollback()
-		else:
-		 self.db.commit()
+ def __exit__(self, *args):
+ if args and args[0] is not None:
+ self.db.rollback()
+ else:
+ self.db.commit()
 
 4. Example 1 rewritten without a generator:
 
@@ -166,9 +171,9 @@
 def __init__(self, lock):
 self.lock = lock
 def __enter__(self):
-	 self.lock.acquire()
+ self.lock.acquire()
 def __exit__(self, *args):
-	 self.lock.release()
+ self.lock.release()
 
 (This example is easily modified to implement the other
 examples; it shows how much simpler generators are for the same
@@ -179,11 +184,9 @@
 @do_template
 def redirecting_stdout(new_stdout):
 save_stdout = sys.stdout
- try:
- sys.stdout = new_stdout
- yield None
- finally:
- sys.stdout = save_stdout
+ sys.stdout = new_stdout
+ yield None
+ sys.stdout = save_stdout
 
 Used as follows:
 
@@ -200,7 +203,7 @@
 except IOError, err:
 yield None, err
 else:
-	 yield f, None
+ yield f, None
 f.close()
 
 Used as follows:


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /