Browse Source
This implements .pend_throw(exc) method, which sets up an exception to be triggered on the next call to generator's .__next__() or .send() method. This is unlike .throw(), which immediately starts to execute the generator to process the exception. This effectively adds Future-like capabilities to generator protocol (exception will be raised in the future). The need for such a method arised to implement uasyncio wait_for() function efficiently (its behavior is clearly "Future" like, and normally would require to introduce an expensive Future wrapper around all native couroutines, like upstream asyncio does). py/objgenerator: pend_throw: Return previous pended value. This effectively allows to store an additional value (not necessary an exception) in a coroutine while it's not being executed. uasyncio has exactly this usecase: to mark a coro waiting in I/O queue (and thus not executed in the normal scheduling queue), for the purpose of implementing wait_for() function (cancellation of such waiting coro by a timeout).pull/3422/merge
Paul Sokolovsky
7 years ago
5 changed files with 68 additions and 3 deletions
@ -0,0 +1,26 @@ |
|||
def gen(): |
|||
i = 0 |
|||
while 1: |
|||
yield i |
|||
i += 1 |
|||
|
|||
g = gen() |
|||
|
|||
try: |
|||
g.pend_throw |
|||
except AttributeError: |
|||
print("SKIP") |
|||
raise SystemExit |
|||
|
|||
|
|||
print(next(g)) |
|||
print(next(g)) |
|||
g.pend_throw(ValueError()) |
|||
|
|||
v = None |
|||
try: |
|||
v = next(g) |
|||
except Exception as e: |
|||
print("raised", repr(e)) |
|||
|
|||
print("ret was:", v) |
@ -0,0 +1,4 @@ |
|||
0 |
|||
1 |
|||
raised ValueError() |
|||
ret was: None |
Loading…
Reference in new issue