[Python-checkins] r42697 - peps/trunk/pep-0343.txt
guido.van.rossum
python-checkins at python.org
Tue Feb 28 23:49:19 CET 2006
Author: guido.van.rossum
Date: Tue Feb 28 23:49:15 2006
New Revision: 42697
Modified:
peps/trunk/pep-0343.txt
Log:
Fix two examples that were broken by the new semantics.
Modified: peps/trunk/pep-0343.txt
==============================================================================
--- peps/trunk/pep-0343.txt (original)
+++ peps/trunk/pep-0343.txt Tue Feb 28 23:49:15 2006
@@ -576,7 +576,7 @@
The tense used in the names of the example context managers is not
arbitrary. Past tense ("-ed") is used when the name refers to an
action which is done in the __enter__ method and undone in the
- __exit__ method. Progressive tense ("-ing") is used when the name
+ __exit__ method. Progressive tense ("-ing") is used when the name
refers to an action which is to be done in the __exit__ method.
1. A template for ensuring that a lock, acquired at the start of a
@@ -643,6 +643,8 @@
self.lock.acquire()
def __exit__(self, type, value, tb):
self.lock.release()
+ if type is not None:
+ raise type, value, tb
(This example is easily modified to implement the other
relatively stateless examples; it shows that it is easy to avoid
@@ -769,34 +771,35 @@
# General Decimal Arithmetic Specification
return +s # Convert result to normal context
- 10. A generic "object-closing" template:
+ 10. A generic "object-closing" template:
- @contextmanager
- def closing(obj):
- try:
- yield obj
- finally:
- try:
- close = obj.close
- except AttributeError:
- pass
- else:
- close()
-
- This can be used to deterministically close anything with a
- close method, be it file, generator, or something else. It can
- even be used when the object isn't guaranteed to require
- closing (e.g., a function that accepts an arbitrary iterable):
-
- # emulate opening():
- with closing(open("argument.txt")) as contradiction:
- for line in contradiction:
- print line
-
- # deterministically finalize an iterator:
- with closing(iter(data_source)) as data:
- for datum in data:
- process(datum)
+ @contextmanager
+ def closing(obj):
+ try:
+ yield obj
+ finally:
+ try:
+ close = obj.close
+ except AttributeError:
+ pass
+ else:
+ close()
+
+ This can be used to deterministically close anything with a
+ close method, be it file, generator, or something else. It
+ can even be used when the object isn't guaranteed to require
+ closing (e.g., a function that accepts an arbitrary
+ iterable):
+
+ # emulate opening():
+ with closing(open("argument.txt")) as contradiction:
+ for line in contradiction:
+ print line
+
+ # deterministically finalize an iterator:
+ with closing(iter(data_source)) as data:
+ for datum in data:
+ process(datum)
11. Native contexts for objects with acquire/release methods:
@@ -807,7 +810,7 @@
def released(self):
return unlocked(self)
- Sample usage:
+ Sample usage:
with my_lock:
# Operations with the lock held
@@ -820,54 +823,43 @@
supplied contexts from left-to-right to avoid excessive
indentation:
- class nested(object):
- def __init__(self, *contexts):
- self.contexts = contexts
- self.entered = None
-
- def __context__(self):
- return self
-
- def __enter__(self):
- if self.entered is not None:
- raise RuntimeError("Context is not reentrant")
- self.entered = deque()
- vars = []
+ @contextmanager
+ def nested(*contexts):
+ exits = []
+ vars = []
+ exc = (None, None, None)
+ try:
try:
- for context in self.contexts:
+ for context in contexts:
mgr = context.__context__()
- vars.append(mgr.__enter__())
- self.entered.appendleft(mgr)
+ exit = mgr.__exit__
+ enter = mgr.__enter__
+ vars.append(enter())
+ exits.append(exit)
+ yield vars
except:
- self.__exit__(*sys.exc_info())
- raise
- return vars
-
- def __exit__(self, *exc_info):
- # Behave like nested with statements
- # first in, last out
- # New exceptions override old ones
- ex = exc_info
- for mgr in self.entered:
+ exc = sys.exc_info()
+ finally:
+ while exits:
+ exit = exits.pop()
try:
- mgr.__exit__(*ex)
+ exit(*exc)
except:
- ex = sys.exc_info()
- self.entered = None
- if ex is not exc_info:
- raise ex[0], ex[1], ex[2]
+ exc = sys.exc_info()
+ if exc != (None, None, None):
+ raise
- Sample usage:
+ Sample usage:
- with nested(a, b, c) as (x, y, z):
- # Perform operation
+ with nested(a, b, c) as (x, y, z):
+ # Perform operation
- Is equivalent to:
+ Is equivalent to:
- with a as x:
- with b as y:
- with c as z:
- # Perform operation
+ with a as x:
+ with b as y:
+ with c as z:
+ # Perform operation
Reference Implementation
@@ -911,6 +903,8 @@
[12]
http://sourceforge.net/tracker/index.php?func=detail&aid=1223381&group_id=5470&atid=305470
+ [13]
+ http://mail.python.org/pipermail/python-dev/2006-February/061903.html
Copyright
More information about the Python-checkins
mailing list