Skip to content

Commit c8239ed

Browse files
committed
make run_cell_async a regular coroutine
separate "should it be async" to a `should_run_async` public method
1 parent 9983091 commit c8239ed

File tree

1 file changed

+68
-39
lines changed

1 file changed

+68
-39
lines changed

IPython/core/interactiveshell.py

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2815,32 +2815,74 @@ def _run_cell(self, raw_cell:str, store_history:bool, silent:bool, shell_futures
28152815
shell_futures=shell_futures,
28162816
)
28172817

2818-
# run_cell_async is async, but may not actually need and eventloop.
2818+
# run_cell_async is async, but may not actually need an eventloop.
28192819
# when this is the case, we want to run it using the pseudo_sync_runner
28202820
# so that code can invoke eventloops (for example via the %run , and
28212821
# `%paste` magic.
2822+
if self.should_run_async(raw_cell):
2823+
runner = self.loop_runner
2824+
else:
2825+
2826+
runner = _pseudo_sync_runner
2827+
28222828
try:
2823-
interactivity = coro.send(None)
2824-
except StopIteration as exc:
2825-
return exc.value
2829+
return runner(coro)
2830+
except Exception as e:
2831+
info = ExecutionInfo(raw_cell, store_history, silent, shell_futures)
2832+
result = ExecutionResult(info)
2833+
result.error_in_exec = e
2834+
self.showtraceback(running_compiled_code=True)
2835+
return result
2836+
return
28262837

2827-
# if code was not async, sending `None` was actually executing the code.
2828-
if isinstance(interactivity, ExecutionResult):
2829-
return interactivity
2838+
def should_run_async(self, raw_cell: str) -> bool:
2839+
"""Return whether a cell should be run asynchronously
28302840
2831-
if interactivity == 'async':
2832-
try:
2833-
return self.loop_runner(coro)
2834-
except Exception as e:
2835-
info = ExecutionInfo(raw_cell, store_history, silent, shell_futures)
2836-
result = ExecutionResult(info)
2837-
result.error_in_exec = e
2838-
self.showtraceback(running_compiled_code=True)
2839-
return result
2840-
return _pseudo_sync_runner(coro)
2841+
Parameters
2842+
----------
2843+
cell: str
2844+
The code to be executed
2845+
2846+
Returns
2847+
-------
2848+
result: bool
2849+
Whether the code should be run asynchronously or not
2850+
"""
2851+
if not self.autoawait:
2852+
return False
2853+
try:
2854+
cell = self.transform_cell(raw_cell)
2855+
except Exception:
2856+
# any exception during transform will be raised
2857+
# prior to execution
2858+
return False
2859+
return _should_be_async(cell)
2860+
2861+
def transform_cell(self, raw_cell: str) -> str:
2862+
"""Transform a raw cell into Python code to be executed
2863+
2864+
Parameters
2865+
----------
2866+
raw_cell: str
2867+
The IPython-syntax code to be executed
2868+
2869+
Returns
2870+
-------
2871+
cell: str
2872+
Transformed Python code to be executed
2873+
"""
2874+
# Static input transformations
2875+
cell = self.input_transformer_manager.transform_cell(raw_cell)
2876+
if len(cell.splitlines()) == 1:
2877+
# Dynamic transformations - only applied for single line commands
2878+
with self.builtin_trap:
2879+
# use prefilter_lines to handle trailing newlines
2880+
# restore trailing newline for ast.parse
2881+
cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2882+
return cell
28412883

28422884
@asyncio.coroutine
2843-
def run_cell_async(self, raw_cell:str, store_history=False, silent=False, shell_futures=True) -> ExecutionResult:
2885+
def run_cell_async(self, raw_cell: str, store_history=False, silent=False, shell_futures=True) -> ExecutionResult:
28442886
"""Run a complete IPython cell asynchronously.
28452887
28462888
Parameters
@@ -2895,24 +2937,13 @@ def error_before_exec(value):
28952937
# prefilter_manager) raises an exception, we store it in this variable
28962938
# so that we can display the error after logging the input and storing
28972939
# it in the history.
2898-
preprocessing_exc_tuple = None
28992940
try:
2900-
# Static input transformations
2901-
cell = self.input_transformer_manager.transform_cell(raw_cell)
2902-
except SyntaxError:
2941+
cell = self.transform_cell(raw_cell)
2942+
except Exception:
2943+
cell = raw_cell
29032944
preprocessing_exc_tuple = sys.exc_info()
2904-
cell = raw_cell # cell has to exist so it can be stored/logged
29052945
else:
2906-
if len(cell.splitlines()) == 1:
2907-
# Dynamic transformations - only applied for single line commands
2908-
with self.builtin_trap:
2909-
try:
2910-
# use prefilter_lines to handle trailing newlines
2911-
# restore trailing newline for ast.parse
2912-
cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2913-
except Exception:
2914-
# don't allow prefilter errors to crash IPython
2915-
preprocessing_exc_tuple = sys.exc_info()
2946+
preprocessing_exc_tuple = None
29162947

29172948
# Store raw and processed history
29182949
if store_history:
@@ -2941,7 +2972,7 @@ def error_before_exec(value):
29412972
with self.display_trap:
29422973
# Compile to bytecode
29432974
try:
2944-
if self.autoawait and _should_be_async(cell):
2975+
if self.should_run_async(cell):
29452976
# the code AST below will not be user code: we wrap it
29462977
# in an `async def`. This will likely make some AST
29472978
# transformer below miss some transform opportunity and
@@ -2987,12 +3018,10 @@ def error_before_exec(value):
29873018
interactivity = "none" if silent else self.ast_node_interactivity
29883019
if _run_async:
29893020
interactivity = 'async'
2990-
# yield interactivity so let run_cell decide whether to use
2991-
# an async loop_runner
2992-
yield interactivity
3021+
29933022
has_raised = yield from self.run_ast_nodes(code_ast.body, cell_name,
29943023
interactivity=interactivity, compiler=compiler, result=result)
2995-
3024+
29963025
self.last_execution_succeeded = not has_raised
29973026
self.last_execution_result = result
29983027

@@ -3008,7 +3037,7 @@ def error_before_exec(value):
30083037
self.execution_count += 1
30093038

30103039
return result
3011-
3040+
30123041
def transform_ast(self, node):
30133042
"""Apply the AST transformations from self.ast_transformers
30143043

0 commit comments

Comments
 (0)