Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 21 additions & 9 deletions dash/_jupyter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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():
Expand All @@ -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

Expand Down Expand Up @@ -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"]
Expand Down