##// END OF EJS Templates
fix runnign on 3.7
Matthias Bussonnier -
Show More
@@ -1,88 +1,90 b''
1 """
1 """
2 Async helper function that are invalid syntax on Python 3.5 and below.
2 Async helper function that are invalid syntax on Python 3.5 and below.
3
3
4 Known limitation and possible improvement.
4 Known limitation and possible improvement.
5
5
6 Top level code that contain a return statement (instead of, or in addition to
6 Top level code that contain a return statement (instead of, or in addition to
7 await) will be detected as requiring being wrapped in async calls. This should
7 await) will be detected as requiring being wrapped in async calls. This should
8 be prevented as early return will not work.
8 be prevented as early return will not work.
9 """
9 """
10
10
11
11
12
12
13 import ast
13 import ast
14 import sys
14 import sys
15 import inspect
15 import inspect
16 from textwrap import dedent, indent
16 from textwrap import dedent, indent
17 from types import CodeType
17 from types import CodeType
18
18
19
19
20 def _asyncio_runner(coro):
20 def _asyncio_runner(coro):
21 """
21 """
22 Handler for asyncio autoawait
22 Handler for asyncio autoawait
23 """
23 """
24 import asyncio
24 import asyncio
25 return asyncio.get_event_loop().run_until_complete(coro)
25 return asyncio.get_event_loop().run_until_complete(coro)
26
26
27
27
28 def _curio_runner(coroutine):
28 def _curio_runner(coroutine):
29 """
29 """
30 handler for curio autoawait
30 handler for curio autoawait
31 """
31 """
32 import curio
32 import curio
33 return curio.run(coroutine)
33 return curio.run(coroutine)
34
34
35
35
36 if sys.version_info > (3, 5):
36 if sys.version_info > (3, 5):
37 # nose refuses to avoid this file and async def is invalidsyntax
37 # nose refuses to avoid this file and async def is invalidsyntax
38 s = dedent('''
38 s = dedent('''
39 def _trio_runner(function):
39 def _trio_runner(function):
40 import trio
40 import trio
41 async def loc(coro):
41 async def loc(coro):
42 """
42 """
43 We need the dummy no-op async def to protect from
43 We need the dummy no-op async def to protect from
44 trio's internal. See https://github.com/python-trio/trio/issues/89
44 trio's internal. See https://github.com/python-trio/trio/issues/89
45 """
45 """
46 return await coro
46 return await coro
47 return trio.run(loc, function)
47 return trio.run(loc, function)
48 ''')
48 ''')
49 exec(s, globals(), locals())
49 exec(s, globals(), locals())
50
50
51
51
52 def _asyncify(code: str) -> str:
52 def _asyncify(code: str) -> str:
53 """wrap code in async def definition.
53 """wrap code in async def definition.
54
54
55 And setup a bit of context to run it later.
55 And setup a bit of context to run it later.
56 """
56 """
57 res = dedent("""
57 res = dedent("""
58 async def __wrapper__():
58 async def __wrapper__():
59 try:
59 try:
60 {usercode}
60 {usercode}
61 finally:
61 finally:
62 locals()
62 locals()
63 """).format(usercode=indent(code, ' ' * 8)[8:])
63 """).format(usercode=indent(code, ' ' * 8)[8:])
64 return res
64 return res
65
65
66
66
67 def _should_be_async(cell: str) -> bool:
67 def _should_be_async(cell: str) -> bool:
68 """Detect if a block of code need to be wrapped in an `async def`
68 """Detect if a block of code need to be wrapped in an `async def`
69
69
70 Attempt to parse the block of code, it it compile we're fine.
70 Attempt to parse the block of code, it it compile we're fine.
71 Otherwise we wrap if and try to compile.
71 Otherwise we wrap if and try to compile.
72
72
73 If it works, assume it should be async. Otherwise Return False.
73 If it works, assume it should be async. Otherwise Return False.
74
74
75 Not handled yet: If the block of code has a return statement as the top
75 Not handled yet: If the block of code has a return statement as the top
76 level, it will be seen as async. This is a know limitation.
76 level, it will be seen as async. This is a know limitation.
77 """
77 """
78
78
79 try:
79 try:
80 ast.parse(cell)
80 # we can't limit ourself to ast.parse, as it __accepts__ to parse on
81 # 3.7+, but just does not _compile_
82 compile(cell, '<>', 'exec')
81 return False
83 return False
82 except SyntaxError:
84 except SyntaxError:
83 try:
85 try:
84 ast.parse(_asyncify(cell))
86 ast.parse(_asyncify(cell))
85 except SyntaxError:
87 except SyntaxError:
86 return False
88 return False
87 return True
89 return True
88 return False
90 return False
General Comments 0
You need to be logged in to leave comments. Login now