Skip to content
14 changes: 14 additions & 0 deletions ipykernel/zmqshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
from ipykernel.displayhook import ZMQShellDisplayHook
from ipykernel.jsonutil import encode_images, json_clean

try:
from IPython.core.history import HistoryOutput
except ImportError:
HistoryOutput = None

# -----------------------------------------------------------------------------
# Functions and classes
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -115,6 +120,15 @@ def publish( # type:ignore[override]
update : bool, optional, keyword-only
If True, send an update_display_data message instead of display_data.
"""
if (
self.shell is not None
and hasattr(self.shell, "history_manager")
and HistoryOutput is not None
):
outputs = self.shell.history_manager.outputs
outputs[self.shell.execution_count].append(
HistoryOutput(output_type="display_data", bundle=data)
)
self._flush_streams()
if metadata is None:
metadata = {}
Expand Down
21 changes: 21 additions & 0 deletions tests/test_zmq_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,27 @@ def test_unregister_hook(self):
second = self.disp_pub.unregister_hook(hook)
assert not bool(second)

def test_display_stored_in_history(self):
"""
Test that published display data gets stored in shell history
for %notebook magic support.
"""
# Mock shell with history manager
mock_shell = MagicMock()
mock_shell.execution_count = 1
mock_shell.history_manager.outputs = {1: []}

self.disp_pub.shell = mock_shell

data = {"text/plain": "test output"}
self.disp_pub.publish(data)

# Check that output was stored in history
stored_outputs = mock_shell.history_manager.outputs[1]
assert len(stored_outputs) == 1
assert stored_outputs[0].output_type == "display_data"
assert stored_outputs[0].bundle == data


def test_magics(tmp_path):
context = zmq.Context()
Expand Down
Loading