##// END OF EJS Templates
att triio runner at top level now that 3.4 drop + docs
att triio runner at top level now that 3.4 drop + docs

File last commit:

r24480:9f6be155
r24480:9f6be155
Show More
async_helpers.py
89 lines | 2.2 KiB | text/x-python | PythonLexer
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463 """
Async helper function that are invalid syntax on Python 3.5 and below.
Known limitation and possible improvement.
Top level code that contain a return statement (instead of, or in addition to
await) will be detected as requiring being wrapped in async calls. This should
be prevented as early return will not work.
"""
import ast
import sys
import inspect
from textwrap import dedent, indent
from types import CodeType
def _asyncio_runner(coro):
"""
Handler for asyncio autoawait
"""
import asyncio
Matthias Bussonnier
reformat with black
r24474
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463 return asyncio.get_event_loop().run_until_complete(coro)
def _curio_runner(coroutine):
"""
handler for curio autoawait
"""
import curio
Matthias Bussonnier
reformat with black
r24474
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463 return curio.run(coroutine)
Matthias Bussonnier
att triio runner at top level now that 3.4 drop + docs
r24480 def _trio_runner(function):
import trio
async def loc(coro):
"""
We need the dummy no-op async def to protect from
trio's internal. See https://github.com/python-trio/trio/issues/89
"""
return await coro
return trio.run(loc, function)
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463
def _asyncify(code: str) -> str:
"""wrap code in async def definition.
And setup a bit of context to run it later.
"""
Matthias Bussonnier
reformat with black
r24474 res = dedent(
"""
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463 async def __wrapper__():
try:
{usercode}
finally:
locals()
Matthias Bussonnier
reformat with black
r24474 """
).format(usercode=indent(code, " " * 8)[8:])
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463 return res
def _should_be_async(cell: str) -> bool:
"""Detect if a block of code need to be wrapped in an `async def`
Attempt to parse the block of code, it it compile we're fine.
Otherwise we wrap if and try to compile.
If it works, assume it should be async. Otherwise Return False.
Not handled yet: If the block of code has a return statement as the top
level, it will be seen as async. This is a know limitation.
"""
try:
Matthias Bussonnier
fix runnign on 3.7
r24468 # we can't limit ourself to ast.parse, as it __accepts__ to parse on
# 3.7+, but just does not _compile_
Matthias Bussonnier
reformat with black
r24474 compile(cell, "<>", "exec")
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463 return False
except SyntaxError:
try:
ast.parse(_asyncify(cell))
Matthias Bussonnier
doc, remove appveyor 3.4
r24475 # TODO verify ast has not "top level" return or yield.
Matthias Bussonnier
Prototype async REPL using IPython, take III...
r24463 except SyntaxError:
return False
return True
return False