[Python-Dev] PEP 479 and asyncio (original) (raw)

Victor Stinner victor.stinner at gmail.com
Thu Nov 27 22:54:32 CET 2014


2014-11-27 20:06 GMT+01:00 Guido van Rossum <guido at python.org>:

The issue here is that asyncio only interprets StopIteration as returning from the generator (with a possible value),

I'm not sure that the issue is directly related to asyncio.

trollius_coro() raises a StopIteration to return the result to caller. To caller is "result = yield from coro", it's not the complex Task._step() method. So it's pure Python, except if I missed something.

The only way out I can think of is to have asyncio special-case the Return exception -- we could do that by defining a new exception (e.g. AlternateReturn) in asyncio that gets treated the same way as StopIteration, so that Trollius can inherit from AlternateReturn (if it exists).

I don't see how it would work.

Here is a simplified example of my issue. You need to modify all "yield from coro" to write instead "yield from catch_return(coro)", or I missed something important.

PEP479 = True if not PEP479: # trollius: no need for catch_return() before the PEP 479 class Return(StopIteration): pass else: # PEP 479: need catch_return() class Return(Exception): def init(self, value): self.value = value

def return_value(value): if 0: yield raise Return(value)

def catch_return(gen): try: value = (yield from gen) except Return as exc: return exc.value

def add_one(gen): value = (yield from gen) return value + 1

def consume_generator(gen): while True: try: next(gen) except StopIteration as exc: return exc.value

gen1 = return_value(3) if PEP479: gen1 = catch_return(gen1) gen2 = add_one(gen1) print(consume_generator(gen2))

Victor



More information about the Python-Dev mailing list