py-backwards icon indicating copy to clipboard operation
py-backwards copied to clipboard

wishlist: asyncio desugaring

Open chrysn opened this issue 7 years ago • 9 comments

python 3.5 and 3.6 have made asynchronous code much more straightforward to write, and while there were some changes in the execution model, much code can run with just desugaring, for example

  • async def f(x): return 1 + await g(x)@asyncio.coroutine / def f(x): return 1 + (yield from g(x)) (3.5 → 3.4, PEP492)
  • async for x in results: print(x)
    tmp = results.__aiter__()
    while True:
        try:
            x = yield from tmp
        except asyncio.StopAsyncIteration:
            break
        print(x)
    
    (3.5 → 3.4, complete form in PEP492)
  • desugaring async def f(x): yield 1; yield 2 according to PEP525 would be a bit more complex, same for PEP530 (3.6 → 3.5)

Some backward compatibility tricks could also be useful in here (eg. adding __iter__ = __await__ to all classes that define an __await__).

Would that (or which of this would) be feasible for py-backwards to include?

chrysn avatar Apr 28 '17 08:04 chrysn

@chrysn here's something I was messing around with to get async generators working https://gist.github.com/graingert/f19fcca51eec3e27111dc738925f358c/

graingert avatar Jun 05 '17 17:06 graingert

Also would be worth getting the https://pypi.python.org/pypi/trollius package back up and running

graingert avatar Jun 05 '17 17:06 graingert

@graingert seems like it can be done in two steps:

  • target 3.4: transform async into something like in the gist
  • target 2.7: transform asyncio calls to trollius

nvbn avatar Jun 05 '17 17:06 nvbn

@nvbn yep that was the idea behind my code. Happy to license it freely if someone want to make sure it's safe.

graingert avatar Jun 05 '17 17:06 graingert

actually I think it's three steps; @graingert's gist demos the target-3.5 step of async yielding. for target-3.4, the await would need to become yield from. (and on targetting < 3.4 i can't comment).

chrysn avatar Jun 05 '17 17:06 chrysn

@chrysn well no, you'd convert the runtime helper module once

graingert avatar Jun 05 '17 17:06 graingert

@nvbn most of the complexity in trollius was supporting python 2.7 and 3.x at the same time with eval. It was also manually converted from 3.4

A fork of trollius with all of that replaced with py-backwards transpiling would be needed.

graingert avatar Jun 05 '17 17:06 graingert

@chrysn yep, three steps would be better, and there's already "transformer" for yield from.

@graingert we can use https://pypi.python.org/pypi/asyncio for 3.3 and trollius for older version.

Seems like it will be a very complicated transformation =)

nvbn avatar Jun 05 '17 17:06 nvbn

Seems like it will be a very complicated transformation =)

Can we keep the steps independent of each other? (Ie. should we split up the issue by target?)

The 3.5 to 3.4 steps should be by far the easiest (it could be done in a regexp, not that we'd do it that way), and the difficulty of pre-3.4 targets shouldn't keep that back.

chrysn avatar Jun 05 '17 18:06 chrysn