[Python-checkins] r70363 - peps/trunk/pep-0377.txt
nick.coghlan
python-checkins at python.org
Sat Mar 14 08:28:36 CET 2009
Author: nick.coghlan
Date: Sat Mar 14 08:28:35 2009
New Revision: 70363
Log:
Add some more to the rationale section in PEP 377
Modified:
peps/trunk/pep-0377.txt
Modified: peps/trunk/pep-0377.txt
==============================================================================
--- peps/trunk/pep-0377.txt (original)
+++ peps/trunk/pep-0377.txt Sat Mar 14 08:28:35 2009
@@ -129,40 +129,95 @@
# instead of as classes!)
class CM(object):
def __init__(self):
- self.cmA = None
- self.cmB = None
+ self.cmA = None
+ self.cmB = None
def __enter__(self):
- if self.cmA is not None:
- raise RuntimeError("Can't re-use this CM")
- self.cmA = cmA()
- self.cmA.__enter__()
- try:
- self.cmB = cmB()
- self.cmB.__enter__()
- except:
- self.cmA.__exit__(*sys.exc_info())
- # Can't suppress in __enter__(), so must raise
+ if self.cmA is not None:
+ raise RuntimeError("Can't re-use this CM")
+ self.cmA = cmA()
+ self.cmA.__enter__()
+ try:
+ self.cmB = cmB()
+ self.cmB.__enter__()
+ except:
+ self.cmA.__exit__(*sys.exc_info())
+ # Can't suppress in __enter__(), so must raise
+ raise
+
+ def __exit__(self, *args):
+ suppress = False
+ try:
+ if self.cmB is not None:
+ suppress = self.cmB.__exit__(*args)
+ except:
+ suppress = self.cmA.__exit__(*sys.exc_info()):
+ if not suppress:
+ # Exception has changed, so reraise explicitly
raise
+ else:
+ if suppress:
+ # cmB already suppressed the exception,
+ # so don't pass it to cmA
+ suppress = self.cmA.__exit__(None, None, None):
+ else:
+ suppress = self.cmA.__exit__(*args):
+ return suppress
+
+With the proposed semantic change in place, the contextlib based examples
+above would then "just work", but the class based version would need
+adjustment to take advantage of the new semantics::
+
+ class CM(object):
+ def __init__(self):
+ self.cmA = None
+ self.cmB = None
+
+ def __enter__(self):
+ if self.cmA is not None:
+ raise RuntimeError("Can't re-use this CM")
+ self.cmA = cmA()
+ self.cmA.__enter__()
+ try:
+ self.cmB = cmB()
+ self.cmB.__enter__()
+ except:
+ if self.cmA.__exit__(*sys.exc_info()):
+ # Suppress the exception, but don't run
+ # the body of the with statement either
+ raise SkipStatement
+ raise
def __exit__(self, *args):
- suppress = False
- try:
- if self.cmB is not None:
- suppress = self.cmB.__exit__(*args)
- except:
- suppress = self.cmA.__exit__(*sys.exc_info()):
- if not suppress:
- # Exception has changed, so reraise explicitly
- raise
+ suppress = False
+ try:
+ if self.cmB is not None:
+ suppress = self.cmB.__exit__(*args)
+ except:
+ suppress = self.cmA.__exit__(*sys.exc_info()):
+ if not suppress:
+ # Exception has changed, so reraise explicitly
+ raise
+ else:
+ if suppress:
+ # cmB already suppressed the exception,
+ # so don't pass it to cmA
+ suppress = self.cmA.__exit__(None, None, None):
else:
- if suppress:
- # cmB already suppressed the exception,
- # so don't pass it to cmA
- suppress = self.cmA.__exit__(None, None, None):
- else:
- suppress = self.cmA.__exit__(*args):
- return suppress
+ suppress = self.cmA.__exit__(*args):
+ return suppress
+
+There is currently a tentative suggestion [3] to add import-style syntax to
+the ``with`` statement to allow multiple context managers to be included in
+a single ``with`` statement without needing to use ``contextlib.nested``. In
+that case the compiler has the option of simply emitting multiple ``with``
+statements at the AST level, thus allowing the semantics of actual nested
+``with`` statements to be reproduced accurately. However, such a change
+would highlight rather than alleviate the problem the current PEP aims to
+address: it would not be possible to use ``contextlib.contextmanager``to
+reliably factor out such ``with`` statements, as they would exhibit exactly
+the same semantic differences as are seen with the ``combined()`` context
+manager in the above example.
Reference Implementation
@@ -186,6 +241,9 @@
.. [2] PEP 343: The "with" Statement
(http://www.python.org/dev/peps/pep-0343/)
+.. [3] Import-style syntax to reduce indentation of nested with statements
+ (http://mail.python.org/pipermail/python-ideas/2009-March/003188.html)
+
Copyright
=========
More information about the Python-checkins
mailing list