summaryrefslogtreecommitdiff
path: root/tests/basics/generator_pend_throw.py
diff options
context:
space:
mode:
authorJim Mussared <jim.mussared@gmail.com>2019-10-29 21:04:55 +1100
committerDamien George <damien.p.george@gmail.com>2019-11-04 15:51:16 +1100
commit5578182ec97509dcc37521b78da5ee31b96f6b4e (patch)
tree59369f5d1bdd3bd3e289406930aa6d0d3cb13079 /tests/basics/generator_pend_throw.py
parent576ed8922472f41dd603da9bd719bd9f1adbf31e (diff)
py/objgenerator: Allow pend_throw to an unstarted generator.
Replace the is_running field with a tri-state variable to indicate running/not-running/pending-exception. Update tests to cover the various cases. This allows cancellation in uasyncio even if the coroutine hasn't been executed yet. Fixes #5242
Diffstat (limited to 'tests/basics/generator_pend_throw.py')
-rw-r--r--tests/basics/generator_pend_throw.py76
1 files changed, 73 insertions, 3 deletions
diff --git a/tests/basics/generator_pend_throw.py b/tests/basics/generator_pend_throw.py
index f00ff793b..ae8c21189 100644
--- a/tests/basics/generator_pend_throw.py
+++ b/tests/basics/generator_pend_throw.py
@@ -13,6 +13,7 @@ except AttributeError:
raise SystemExit
+# Verify that an injected exception will be raised from next().
print(next(g))
print(next(g))
g.pend_throw(ValueError())
@@ -25,7 +26,76 @@ except Exception as e:
print("ret was:", v)
+
+# Verify that pend_throw works on an unstarted coroutine.
+g = gen()
+g.pend_throw(OSError())
+try:
+ next(g)
+except Exception as e:
+ print("raised", repr(e))
+
+
+# Verify that you can't resume the coroutine from within the running coroutine.
+def gen_next():
+ next(g)
+ yield 1
+
+g = gen_next()
+
+try:
+ next(g)
+except Exception as e:
+ print("raised", repr(e))
+
+
+# Verify that you can't pend_throw from within the running coroutine.
+def gen_pend_throw():
+ g.pend_throw(ValueError())
+ yield 1
+
+g = gen_pend_throw()
+
+try:
+ next(g)
+except Exception as e:
+ print("raised", repr(e))
+
+
+# Verify that the pend_throw exception can be ignored.
+class CancelledError(Exception):
+ pass
+
+def gen_cancelled():
+ for i in range(5):
+ try:
+ yield i
+ except CancelledError:
+ print('ignore CancelledError')
+
+g = gen_cancelled()
+print(next(g))
+g.pend_throw(CancelledError())
+print(next(g))
+# ...but not if the generator hasn't started.
+g = gen_cancelled()
+g.pend_throw(CancelledError())
try:
- gen().pend_throw(ValueError())
-except TypeError:
- print("TypeError")
+ next(g)
+except Exception as e:
+ print("raised", repr(e))
+
+
+# Verify that calling pend_throw returns the previous exception.
+g = gen()
+next(g)
+print(repr(g.pend_throw(CancelledError())))
+print(repr(g.pend_throw(OSError)))
+
+
+# Verify that you can pend_throw(None) to cancel a previous pend_throw.
+g = gen()
+next(g)
+g.pend_throw(CancelledError())
+print(repr(g.pend_throw(None)))
+print(next(g))