diff --git a/ipykernel/ipkernel.py b/ipykernel/ipkernel.py index aa22bbb0f..eba728335 100644 --- a/ipykernel/ipkernel.py +++ b/ipykernel/ipkernel.py @@ -392,7 +392,7 @@ async def do_execute( if hasattr(shell, "run_cell_async") and hasattr(shell, "should_run_async"): run_cell = shell.run_cell_async should_run_async = shell.should_run_async - accepts_params = _accepts_parameters(run_cell, ["cell_id"]) + accepts_params = _accepts_parameters(run_cell, ["cell_id", "cell_meta"]) else: should_run_async = lambda cell: False # noqa: ARG005, E731 # older IPython, @@ -401,7 +401,7 @@ async def do_execute( async def run_cell(*args, **kwargs): return shell.run_cell(*args, **kwargs) - accepts_params = _accepts_parameters(shell.run_cell, ["cell_id"]) + accepts_params = _accepts_parameters(shell.run_cell, ["cell_id", "cell_meta"]) try: # default case: runner is asyncio and asyncio is already running # TODO: this should check every case for "are we inside the runner", @@ -413,6 +413,12 @@ async def run_cell(*args, **kwargs): transformed_cell = code preprocessing_exc_tuple = sys.exc_info() + do_execute_args = {} + if accepts_params["cell_meta"]: + do_execute_args["cell_meta"] = cell_meta + if accepts_params["cell_id"]: + do_execute_args["cell_id"] = cell_id + if ( _asyncio_runner # type:ignore[truthy-bool] and shell.loop_runner is _asyncio_runner @@ -423,23 +429,14 @@ async def run_cell(*args, **kwargs): preprocessing_exc_tuple=preprocessing_exc_tuple, ) ): - if accepts_params["cell_id"]: - coro = run_cell( - code, - store_history=store_history, - silent=silent, - transformed_cell=transformed_cell, - preprocessing_exc_tuple=preprocessing_exc_tuple, - cell_id=cell_id, - ) - else: - coro = run_cell( - code, - store_history=store_history, - silent=silent, - transformed_cell=transformed_cell, - preprocessing_exc_tuple=preprocessing_exc_tuple, - ) + coro = run_cell( + code, + store_history=store_history, + silent=silent, + transformed_cell=transformed_cell, + preprocessing_exc_tuple=preprocessing_exc_tuple, + **do_execute_args, + ) coro_future = asyncio.ensure_future(coro) @@ -460,15 +457,9 @@ async def run_cell(*args, **kwargs): # runner isn't already running, # make synchronous call, # letting shell dispatch to loop runners - if accepts_params["cell_id"]: - res = shell.run_cell( - code, - store_history=store_history, - silent=silent, - cell_id=cell_id, - ) - else: - res = shell.run_cell(code, store_history=store_history, silent=silent) + res = shell.run_cell( + code, store_history=store_history, silent=silent, **do_execute_args + ) finally: self._restore_input() diff --git a/ipykernel/kernelbase.py b/ipykernel/kernelbase.py index 7fa1fb9dc..27bd371c9 100644 --- a/ipykernel/kernelbase.py +++ b/ipykernel/kernelbase.py @@ -794,7 +794,7 @@ async def execute_request(self, stream, ident, parent): store_history = content.get("store_history", not silent) user_expressions = content.get("user_expressions", {}) allow_stdin = content.get("allow_stdin", False) - cell_meta = parent.get("metadata", {}) + cell_meta = parent.get("metadata", None) cell_id = cell_meta.get("cellId") except Exception: self.log.error("Got bad msg: ") diff --git a/tests/inprocess/test_kernel.py b/tests/inprocess/test_kernel.py index b965d9b89..ad663313a 100644 --- a/tests/inprocess/test_kernel.py +++ b/tests/inprocess/test_kernel.py @@ -119,3 +119,9 @@ async def test_do_execute(kc): kernel = InProcessKernel() await kernel.do_execute("a=1", True) assert kernel.shell.user_ns["a"] == 1 + + +async def test_cell_meta_do_execute(): + kernel: InProcessKernel = InProcessKernel() + await kernel.do_execute("a=1", True, cell_meta={"testkey": "testvalue"}) + assert kernel.shell.user_ns["a"] == 1