Show More
@@ -149,16 +149,15 b' def _should_be_async(cell: str) -> bool:' | |||||
149 | Not handled yet: If the block of code has a return statement as the top |
|
149 | Not handled yet: If the block of code has a return statement as the top | |
150 | level, it will be seen as async. This is a know limitation. |
|
150 | level, it will be seen as async. This is a know limitation. | |
151 | """ |
|
151 | """ | |
|
152 | if sys.version_info > (3, 8): | |||
|
153 | code = compile(cell, "<>", "exec", flags=getattr(ast,'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0)) | |||
|
154 | return inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE | |||
152 |
|
155 | |||
153 | try: |
|
156 | try: | |
154 | # we can't limit ourself to ast.parse, as it __accepts__ to parse on |
|
157 | # we can't limit ourself to ast.parse, as it __accepts__ to parse on | |
155 | # 3.7+, but just does not _compile_ |
|
158 | # 3.7+, but just does not _compile_ | |
156 | # code = compile(cell, "<>", "exec", flags=getattr(ast,'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0)) |
|
|||
157 | code = compile(cell, "<>", "exec") |
|
159 | code = compile(cell, "<>", "exec") | |
158 | return inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE |
|
|||
159 | except SyntaxError: |
|
160 | except SyntaxError: | |
160 | #if sys.version_info > (3, 8): |
|
|||
161 | # raise |
|
|||
162 | try: |
|
161 | try: | |
163 | parse_tree = _async_parse_cell(cell) |
|
162 | parse_tree = _async_parse_cell(cell) | |
164 |
|
163 |
@@ -17,6 +17,7 b' import asyncio' | |||||
17 | import atexit |
|
17 | import atexit | |
18 | import builtins as builtin_mod |
|
18 | import builtins as builtin_mod | |
19 | import functools |
|
19 | import functools | |
|
20 | import inspect | |||
20 | import os |
|
21 | import os | |
21 | import re |
|
22 | import re | |
22 | import runpy |
|
23 | import runpy | |
@@ -161,8 +162,9 b' def removed_co_newlocals(function:types.FunctionType) -> types.FunctionType:' | |||||
161 | # we still need to run things using the asyncio eventloop, but there is no |
|
162 | # we still need to run things using the asyncio eventloop, but there is no | |
162 | # async integration |
|
163 | # async integration | |
163 | from .async_helpers import (_asyncio_runner, _asyncify, _pseudo_sync_runner) |
|
164 | from .async_helpers import (_asyncio_runner, _asyncify, _pseudo_sync_runner) | |
164 |
|
165 | if sys.version_info > (3, 8): | ||
165 | if sys.version_info > (3, 5): |
|
166 | from .async_helpers import _curio_runner, _trio_runner | |
|
167 | elif sys.version_info > (3, 5): | |||
166 | from .async_helpers import _curio_runner, _trio_runner, _should_be_async |
|
168 | from .async_helpers import _curio_runner, _trio_runner, _should_be_async | |
167 | else : |
|
169 | else : | |
168 | _curio_runner = _trio_runner = None |
|
170 | _curio_runner = _trio_runner = None | |
@@ -3000,7 +3002,8 b' class InteractiveShell(SingletonConfigurable):' | |||||
3000 | with self.display_trap: |
|
3002 | with self.display_trap: | |
3001 | # Compile to bytecode |
|
3003 | # Compile to bytecode | |
3002 | try: |
|
3004 | try: | |
3003 | if self.autoawait and _should_be_async(cell): |
|
3005 | if sys.version_info < (3,8) and self.autoawait: | |
|
3006 | if _should_be_async(cell): | |||
3004 | # the code AST below will not be user code: we wrap it |
|
3007 | # the code AST below will not be user code: we wrap it | |
3005 | # in an `async def`. This will likely make some AST |
|
3008 | # in an `async def`. This will likely make some AST | |
3006 | # transformer below miss some transform opportunity and |
|
3009 | # transformer below miss some transform opportunity and | |
@@ -3019,6 +3022,8 b' class InteractiveShell(SingletonConfigurable):' | |||||
3019 | _run_async = True |
|
3022 | _run_async = True | |
3020 | else: |
|
3023 | else: | |
3021 | code_ast = compiler.ast_parse(cell, filename=cell_name) |
|
3024 | code_ast = compiler.ast_parse(cell, filename=cell_name) | |
|
3025 | else: | |||
|
3026 | code_ast = compiler.ast_parse(cell, filename=cell_name) | |||
3022 | except self.custom_exceptions as e: |
|
3027 | except self.custom_exceptions as e: | |
3023 | etype, value, tb = sys.exc_info() |
|
3028 | etype, value, tb = sys.exc_info() | |
3024 | self.CustomTB(etype, value, tb) |
|
3029 | self.CustomTB(etype, value, tb) | |
@@ -3045,8 +3050,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
3045 | # Execute the user code |
|
3050 | # Execute the user code | |
3046 | interactivity = "none" if silent else self.ast_node_interactivity |
|
3051 | interactivity = "none" if silent else self.ast_node_interactivity | |
3047 | if _run_async: |
|
3052 | if _run_async: | |
3048 |
|
|
3053 | interactivity = 'async' | |
3049 | interactivity = 'last_expr' |
|
|||
3050 |
|
3054 | |||
3051 | has_raised = yield from self.run_ast_nodes(code_ast.body, cell_name, |
|
3055 | has_raised = yield from self.run_ast_nodes(code_ast.body, cell_name, | |
3052 | interactivity=interactivity, compiler=compiler, result=result) |
|
3056 | interactivity=interactivity, compiler=compiler, result=result) | |
@@ -3168,8 +3172,6 b' class InteractiveShell(SingletonConfigurable):' | |||||
3168 | """ |
|
3172 | """ | |
3169 | if not nodelist: |
|
3173 | if not nodelist: | |
3170 | return |
|
3174 | return | |
3171 | if interactivity == 'async': |
|
|||
3172 | interactivify = 'last' |
|
|||
3173 |
|
3175 | |||
3174 | if interactivity == 'last_expr_or_assign': |
|
3176 | if interactivity == 'last_expr_or_assign': | |
3175 | if isinstance(nodelist[-1], _assign_nodes): |
|
3177 | if isinstance(nodelist[-1], _assign_nodes): | |
@@ -3205,10 +3207,11 b' class InteractiveShell(SingletonConfigurable):' | |||||
3205 | else: |
|
3207 | else: | |
3206 | raise ValueError("Interactivity was %r" % interactivity) |
|
3208 | raise ValueError("Interactivity was %r" % interactivity) | |
3207 |
|
3209 | |||
3208 | print('interactivity:', interactivity) |
|
|||
3209 | try: |
|
3210 | try: | |
3210 |
if _async and sys.version_info |
|
3211 | if _async and sys.version_info > (3,8): | |
3211 | raise ValueError |
|
3212 | raise ValueError("This branch should never happen on Python 3.8 and above, " | |
|
3213 | "please try to upgrade IPython and open a bug report with your case.") | |||
|
3214 | if _async: | |||
3212 | # If interactivity is async the semantics of run_code are |
|
3215 | # If interactivity is async the semantics of run_code are | |
3213 | # completely different Skip usual machinery. |
|
3216 | # completely different Skip usual machinery. | |
3214 | mod = Module(nodelist, []) |
|
3217 | mod = Module(nodelist, []) | |
@@ -3218,28 +3221,30 b' class InteractiveShell(SingletonConfigurable):' | |||||
3218 | if (yield from self.run_code(async_code, result, async_=True)): |
|
3221 | if (yield from self.run_code(async_code, result, async_=True)): | |
3219 | return True |
|
3222 | return True | |
3220 | else: |
|
3223 | else: | |
|
3224 | if sys.version_info > (3, 8): | |||
3221 | def compare(code): |
|
3225 | def compare(code): | |
3222 | import inspect |
|
|||
3223 | is_async = (inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE) |
|
3226 | is_async = (inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE) | |
3224 | print('async=', _async, 'autodetect=', is_async) |
|
|||
3225 | return is_async |
|
3227 | return is_async | |
|
3228 | else: | |||
|
3229 | def compare(code): | |||
|
3230 | return _async | |||
3226 |
|
3231 | |||
3227 | # refactor that to just change the mod constructor. |
|
3232 | # refactor that to just change the mod constructor. | |
3228 | for i, node in enumerate(to_run_exec): |
|
3233 | to_run = [] | |
3229 | mod = Module([node], []) |
|
3234 | for node in to_run_exec: | |
3230 | with compiler.extra_flags(getattr(ast, 'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0) if self.autoawait else 0x0): |
|
3235 | to_run.append((node, 'exec')) | |
3231 | code = compiler(mod, cell_name, "exec") |
|
3236 | ||
3232 | asy = compare(code) |
|
3237 | for node in to_run_interactive: | |
3233 | if (yield from self.run_code(code, result, async_=asy)): |
|
3238 | to_run.append((node, 'single')) | |
3234 | return True |
|
|||
3235 |
|
3239 | |||
3236 |
for |
|
3240 | for node,mode in to_run: | |
3237 | print('B: interactive, async=', _async, nodelist) |
|
3241 | if mode == 'exec': | |
|
3242 | mod = Module([node], []) | |||
|
3243 | elif mode == 'single': | |||
3238 | mod = ast.Interactive([node]) |
|
3244 | mod = ast.Interactive([node]) | |
3239 | with compiler.extra_flags(getattr(ast, 'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0) if self.autoawait else 0x0): |
|
3245 | with compiler.extra_flags(getattr(ast, 'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0) if self.autoawait else 0x0): | |
3240 |
code = compiler(mod, cell_name, |
|
3246 | code = compiler(mod, cell_name, mode) | |
3241 | asy = compare(code) |
|
3247 | asy = compare(code) | |
3242 |
|
||||
3243 | if (yield from self.run_code(code, result, async_=asy)): |
|
3248 | if (yield from self.run_code(code, result, async_=asy)): | |
3244 | return True |
|
3249 | return True | |
3245 |
|
3250 |
General Comments 0
You need to be logged in to leave comments.
Login now