Elaborate transaction() manager example (Chris A).
This commit is contained in:
parent
a6b3c8b1f7
commit
90addf57a2
31
pep-0479.txt
31
pep-0479.txt
|
@ -44,26 +44,39 @@ limitation, but notes that "use cases for these [are] rare to non-
|
||||||
existent". Unfortunately while intentional use is rare, it is easy to
|
existent". Unfortunately while intentional use is rare, it is easy to
|
||||||
stumble on these cases by accident::
|
stumble on these cases by accident::
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def transaction():
|
def transaction():
|
||||||
begin()
|
print('begin')
|
||||||
try:
|
try:
|
||||||
yield from do_it()
|
yield from do_it()
|
||||||
except:
|
except:
|
||||||
rollback()
|
print('rollback')
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
commit()
|
print('commit')
|
||||||
|
|
||||||
def do_it():
|
def do_it():
|
||||||
initial_preparations()
|
print('Refactored preparations')
|
||||||
yield
|
yield # Body of with-statement is executed here
|
||||||
finishing_touches()
|
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
|
Here factoring out ``do_it`` into a subgenerator has introduced a
|
||||||
subtle bug: if the wrapped block raises ``StopIteration``, under the
|
subtle bug: if the wrapped block raises ``StopIteration``, under the
|
||||||
current behavior ``do_it`` will fail but report success by returning
|
current behavior this exception will be swallowed by the context
|
||||||
normally, causing the failed transaction to be committed! Similarly
|
manager; and, worse, the finalization is silently skipped! Similarly
|
||||||
problematic behavior occurs when an ``asyncio`` coroutine raises
|
problematic behavior occurs when an ``asyncio`` coroutine raises
|
||||||
``StopIteration``, causing it to terminate silently.
|
``StopIteration``, causing it to terminate silently.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue