def_run_cell(self, raw_cell:str, store_history:bool, silent:bool, shell_futures:bool): """Internal method to run a complete IPython cell.""" coro = self.run_cell_async( raw_cell, store_history=store_history, silent=silent, shell_futures=shell_futures, )
# run_cell_async is async, but may not actually need an eventloop. # when this is the case, we want to run it using the pseudo_sync_runner # so that code can invoke eventloops (for example via the %run , and # `%paste` magic. ifself.trio_runner: runner = self.trio_runner elifself.should_run_async(raw_cell): runner = self.loop_runner else: runner = _pseudo_sync_runner
try: return runner(coro) except BaseException as e: info = ExecutionInfo(raw_cell, store_history, silent, shell_futures) result = ExecutionResult(info) result.error_in_exec = e self.showtraceback(running_compiled_code=True) return result return
asyncdefrun_cell_async(self, raw_cell: str, store_history=False, silent=False, shell_futures=True) -> ExecutionResult: info = ExecutionInfo( raw_cell, store_history, silent, shell_futures) result = ExecutionResult(info) ... # If any of our input transformation (input_transformer_manager or # prefilter_manager) raises an exception, we store it in this variable # so that we can display the error after logging the input and storing # it in the history. try: cell = self.transform_cell(raw_cell) ... # Store raw and processed history ... # Display the exception if input processing failed. ... # Our own compiler remembers the __future__ environment. If we want to # run code with a separate __future__ environment, use the default # compiler compiler = self.compileif shell_futures else CachingCompiler() _run_async = False withself.builtin_trap: cell_name = self.compile.cache(cell, self.execution_count) withself.display_trap: # Compile to bytecode try: if sys.version_info < (3,8) andself.autoawait: if _should_be_async(cell): # the code AST below will not be user code: we wrap it # in an `async def`. This will likely make some AST # transformer below miss some transform opportunity and # introduce a small coupling to run_code (in which we # bake some assumptions of what _ast_asyncify returns. # they are ways around (like grafting part of the ast # later: # - Here, return code_ast.body[0].body[1:-1], as well # as last expression in return statement which is # the user code part. # - Let it go through the AST transformers, and graft # - it back after the AST transform # But that seem unreasonable, at least while we # do not need it. code_ast = _ast_asyncify(cell, 'async-def-wrapper') _run_async = True else: code_ast = compiler.ast_parse(cell, filename=cell_name) else: code_ast = compiler.ast_parse(cell, filename=cell_name) ... # Apply AST transformations try: code_ast = self.transform_ast(code_ast) ... # Execute the user code interactivity = "none"if silent elseself.ast_node_interactivity if _run_async: interactivity = 'async'
has_raised = awaitself.run_ast_nodes(code_ast.body, cell_name, interactivity=interactivity, compiler=compiler, result=result) ... # Reset this so later displayed values do not modify the # ExecutionResult self.displayhook.exec_result = None ... return result