[Python-checkins] peps: Elaborate transaction() manager example (Chris A).
guido.van.rossum
python-checkins at python.org
Sat Nov 29 02:37:14 CET 2014
https://hg.python.org/peps/rev/4803b0829533
changeset: 5624:4803b0829533
user: Guido van Rossum <guido at python.org>
date: Fri Nov 28 17:26:33 2014 -0800
summary:
Elaborate transaction() manager example (Chris A).
files:
pep-0479.txt | 31 ++++++++++++++++++++++---------
1 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/pep-0479.txt b/pep-0479.txt
--- a/pep-0479.txt
+++ b/pep-0479.txt
@@ -44,26 +44,39 @@
existent". Unfortunately while intentional use is rare, it is easy to
stumble on these cases by accident::
+ import contextlib
+
@contextlib.contextmanager
def transaction():
- begin()
+ print('begin')
try:
yield from do_it()
except:
- rollback()
+ print('rollback')
raise
else:
- commit()
-
+ print('commit')
+
def do_it():
- initial_preparations()
- yield
- finishing_touches()
+ print('Refactored preparations')
+ yield # Body of with-statement is executed here
+ print('Refactored finalization')
+
+ def gene():
+ for i in range(2):
+ with transaction():
+ yield i
+ # return
+ raise StopIteration # This is wrong
+ print('Should not be reached')
+
+ for i in gene():
+ print('main: i =', i)
Here factoring out ``do_it`` into a subgenerator has introduced a
subtle bug: if the wrapped block raises ``StopIteration``, under the
-current behavior ``do_it`` will fail but report success by returning
-normally, causing the failed transaction to be committed! Similarly
+current behavior this exception will be swallowed by the context
+manager; and, worse, the finalization is silently skipped! Similarly
problematic behavior occurs when an ``asyncio`` coroutine raises
``StopIteration``, causing it to terminate silently.
--
Repository URL: https://hg.python.org/peps
More information about the Python-checkins
mailing list