diff --git a/CHANGELOG.md b/CHANGELOG.md index 252898131b..7aad387787 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). - [#3395](https://github.com/plotly/dash/pull/3395) Fix Components added through set_props() cannot trigger related callback functions. Fix [#3316](https://github.com/plotly/dash/issues/3316) - [#3397](https://github.com/plotly/dash/pull/3397) Add optional callbacks, suppressing callback warning for missing component ids for a single callback. - [#3415](https://github.com/plotly/dash/pull/3415) Fix the error triggered when only a single no_update is returned for client-side callback functions with multiple Outputs. Fix [#3366](https://github.com/plotly/dash/issues/3366) +- [#3416](https://github.com/plotly/dash/issues/3416) Fix DeprecationWarning in dash/_jupyter.py by migrating from deprecated ipykernel.comm.Comm to comm module ## [3.2.0] - 2025-07-31 diff --git a/dash/_jupyter.py b/dash/_jupyter.py index ac06f849c7..4211c81164 100644 --- a/dash/_jupyter.py +++ b/dash/_jupyter.py @@ -22,12 +22,12 @@ from IPython.core.display import HTML from IPython.core.ultratb import FormattedTB from retrying import retry - from ipykernel.comm import Comm + from comm import create_comm import nest_asyncio import requests - _dash_comm = Comm(target_name="dash") + _dash_comm = create_comm(target_name="dash") _dep_installed = True except ImportError: _dep_installed = False @@ -97,10 +97,14 @@ def convert(name, locals=locals, formatarg=formatarg, formatvalue=formatvalue): def _send_jupyter_config_comm_request(): # If running in an ipython kernel, # request that the front end extension send us the notebook server base URL - if get_ipython() is not None: - if _dash_comm.kernel is not None: - _caller["parent"] = _dash_comm.kernel.get_parent() - _dash_comm.send({"type": "base_url_request"}) + ipython = get_ipython() + if ( + ipython is not None + and hasattr(ipython, "kernel") + and ipython.kernel is not None + ): + _caller["parent"] = ipython.kernel.get_parent() + _dash_comm.send({"type": "base_url_request"}) def _jupyter_comm_response_received(): @@ -109,7 +113,8 @@ def _jupyter_comm_response_received(): def _request_jupyter_config(timeout=2): # Heavily inspired by implementation of CaptureExecution in the - if _dash_comm.kernel is None: + ipython = get_ipython() + if ipython is None or not hasattr(ipython, "kernel") or ipython.kernel is None: # Not in jupyter setting return @@ -215,8 +220,15 @@ def __init__(self): @_dash_comm.on_msg def _receive_message(msg): prev_parent = _caller.get("parent") - if prev_parent and prev_parent != _dash_comm.kernel.get_parent(): - _dash_comm.kernel.set_parent( + ipython = get_ipython() + if ( + prev_parent + and ipython is not None + and hasattr(ipython, "kernel") + and ipython.kernel is not None + and prev_parent != ipython.kernel.get_parent() + ): + ipython.kernel.set_parent( [prev_parent["header"]["session"]], prev_parent ) del _caller["parent"]