Author: Armin Rigo <[email protected]>
Branch: stm
Changeset: r51558:b4fd35482b14
Date: 2012-01-20 18:01 +0100
http://bitbucket.org/pypy/pypy/changeset/b4fd35482b14/
Log: Propagate the exception that occurs in a transaction.
diff --git a/pypy/module/transaction/interp_transaction.py
b/pypy/module/transaction/interp_transaction.py
--- a/pypy/module/transaction/interp_transaction.py
+++ b/pypy/module/transaction/interp_transaction.py
@@ -89,9 +89,13 @@
@staticmethod
def _run_in_transaction(pending):
- space = state.space
- space.call_args(pending.w_callback, pending.args)
- # xxx exceptions?
+ if state.got_exception is not None:
+ return # return early if there is already a 'got_exception'
+ try:
+ space = state.space
+ space.call_args(pending.w_callback, pending.args)
+ except Exception, e:
+ state.got_exception = e
def add(space, w_callback, __args__):
@@ -159,6 +163,7 @@
state.num_waiting_threads = 0
state.finished = False
state.running = True
+ state.got_exception = None
#
for i in range(state.num_threads):
threadintf.start_new_thread(_run_thread, ())
@@ -170,3 +175,9 @@
assert state.pending_lists.keys() == [state.main_thread_id]
assert not state.is_locked_no_tasks_pending()
state.running = False
+ #
+ # now re-raise the exception that we got in a transaction
+ if state.got_exception is not None:
+ e = state.got_exception
+ state.got_exception = None
+ raise e
diff --git a/pypy/module/transaction/test/test_transaction.py
b/pypy/module/transaction/test/test_transaction.py
--- a/pypy/module/transaction/test/test_transaction.py
+++ b/pypy/module/transaction/test/test_transaction.py
@@ -41,3 +41,21 @@
for index in range(7):
assert lst[start + index] == lst[start] + index
assert seen == set([10, 20, 30])
+
+ def test_propagate_exception(self):
+ import transaction, time
+ lst = []
+ def f(n):
+ lst.append(n)
+ time.sleep(0.5)
+ raise ValueError(n)
+ transaction.add(f, 10)
+ transaction.add(f, 20)
+ transaction.add(f, 30)
+ try:
+ transaction.run()
+ assert 0, "should have raised ValueError"
+ except ValueError, e:
+ pass
+ assert len(lst) == 1
+ assert lst[0] == e.args[0]
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit