[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

changeset:   5624:4803b0829533
user:        Guido van Rossum <guido at python.org>
date:        Fri Nov 28 17:26:33 2014 -0800
  Elaborate transaction() manager example (Chris A).

  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
     def transaction():
-        begin()
+        print('begin')
             yield from do_it()
-            rollback()
+            print('rollback')
-            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