From 6945807a3f15548c9e5e2f70e442b22049e1ba69 Mon Sep 17 00:00:00 2001 From: philippe Date: Fri, 10 May 2024 11:29:31 -0400 Subject: [PATCH 1/5] Fix multi set_props calls --- dash/_callback_context.py | 6 ++++- .../callbacks/test_arbitrary_callbacks.py | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/dash/_callback_context.py b/dash/_callback_context.py index aaa721369e..a60431c9c6 100644 --- a/dash/_callback_context.py +++ b/dash/_callback_context.py @@ -252,7 +252,11 @@ def timing_information(self): def set_props(self, component_id: typing.Union[str, dict], props: dict): ctx_value = _get_context_value() _id = stringify_id(component_id) - ctx_value.updated_props[_id] = props + updates = ctx_value.updated_props.get(_id) + if updates is not None: + ctx_value.updated_props[_id] = {**updates, **props} + else: + ctx_value.updated_props[_id] = props callback_context = CallbackContext() diff --git a/tests/integration/callbacks/test_arbitrary_callbacks.py b/tests/integration/callbacks/test_arbitrary_callbacks.py index 4441c44add..b9230baa8d 100644 --- a/tests/integration/callbacks/test_arbitrary_callbacks.py +++ b/tests/integration/callbacks/test_arbitrary_callbacks.py @@ -165,3 +165,26 @@ def on_click(clicked): ".dash-fe-error__title", "Callback error with no output from input start.n_clicks", ) + + +def test_arb006_multi_set_props(dash_duo): + app = Dash() + + app.layout = [ + html.Button("start", id="start"), + html.Div("initial", id="output"), + ] + + @app.callback( + Input("start", "n_clicks"), + ) + def on_click(_): + set_props("output", {"children": "changed"}) + set_props("output", {"style": {"background": "rgb(255,0,0)"}}) + + dash_duo.start_server(app) + dash_duo.wait_for_element("#start").click() + dash_duo.wait_for_text_to_equal("#output", "changed") + dash_duo.wait_for_style_to_equal( + "#output", "background-color", "rgba(255, 0, 0, 1)" + ) From 06d9a4fbbce326795019769a636bddd29512558f Mon Sep 17 00:00:00 2001 From: philippe Date: Fri, 10 May 2024 12:16:15 -0400 Subject: [PATCH 2/5] Fix multi set_props in background callbacks. --- dash/long_callback/_proxy_set_props.py | 6 ++++++ tests/integration/long_callback/app_arbitrary.py | 2 ++ .../long_callback/test_basic_long_callback017.py | 3 +++ 3 files changed, 11 insertions(+) diff --git a/dash/long_callback/_proxy_set_props.py b/dash/long_callback/_proxy_set_props.py index 52f0af70a6..f72fcf3737 100644 --- a/dash/long_callback/_proxy_set_props.py +++ b/dash/long_callback/_proxy_set_props.py @@ -7,6 +7,12 @@ class ProxySetProps(dict): def __init__(self, on_change): super().__init__() self.on_change = on_change + self._data = {} def __setitem__(self, key, value): self.on_change(key, value) + self._data.setdefault(key, {}) + self._data[key] = {**self._data[key], **value} + + def get(self, key): + return self._data.get(key) diff --git a/tests/integration/long_callback/app_arbitrary.py b/tests/integration/long_callback/app_arbitrary.py index e09f08de34..939fce8334 100644 --- a/tests/integration/long_callback/app_arbitrary.py +++ b/tests/integration/long_callback/app_arbitrary.py @@ -25,9 +25,11 @@ Input("start", "n_clicks"), prevent_initial_call=True, background=True, + interval=500, ) def on_click(_): set_props("secondary", {"children": "first"}) + set_props("secondary", {"style": {"background": "red"}}) time.sleep(2) set_props("secondary", {"children": "second"}) return "completed" diff --git a/tests/integration/long_callback/test_basic_long_callback017.py b/tests/integration/long_callback/test_basic_long_callback017.py index bef39d3eed..3d64d39c6d 100644 --- a/tests/integration/long_callback/test_basic_long_callback017.py +++ b/tests/integration/long_callback/test_basic_long_callback017.py @@ -8,6 +8,9 @@ def test_lcbc017_long_callback_set_props(dash_duo, manager): dash_duo.find_element("#start").click() dash_duo.wait_for_text_to_equal("#secondary", "first") + dash_duo.wait_for_style_to_equal( + "#secondary", "background-color", "rgba(255, 0, 0, 1)" + ) dash_duo.wait_for_text_to_equal("#output", "initial") dash_duo.wait_for_text_to_equal("#secondary", "second") dash_duo.wait_for_text_to_equal("#output", "completed") From 6134e4d2e0a4c10991ad751584fe6a9b919b13fe Mon Sep 17 00:00:00 2001 From: philippe Date: Mon, 13 May 2024 14:29:58 -0400 Subject: [PATCH 3/5] rename var updates -> existing --- dash/_callback_context.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dash/_callback_context.py b/dash/_callback_context.py index a60431c9c6..756b2c36b3 100644 --- a/dash/_callback_context.py +++ b/dash/_callback_context.py @@ -252,9 +252,9 @@ def timing_information(self): def set_props(self, component_id: typing.Union[str, dict], props: dict): ctx_value = _get_context_value() _id = stringify_id(component_id) - updates = ctx_value.updated_props.get(_id) - if updates is not None: - ctx_value.updated_props[_id] = {**updates, **props} + existing = ctx_value.updated_props.get(_id) + if existing is not None: + ctx_value.updated_props[_id] = {**existing, **props} else: ctx_value.updated_props[_id] = props From 8229a0eeb566a89659522df99bb17a09e6141a50 Mon Sep 17 00:00:00 2001 From: philippe Date: Mon, 13 May 2024 15:28:07 -0400 Subject: [PATCH 4/5] build From 73f32666b5aad8e976454d8f0cb0467e065a1a0b Mon Sep 17 00:00:00 2001 From: philippe Date: Tue, 14 May 2024 13:07:09 -0400 Subject: [PATCH 5/5] Update changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index afb766f810..bee960d70f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). - [#2854](https://github.com/plotly/dash/pull/2854) Fix dcc.Dropdown resetting empty values to null and triggering callbacks. Fixes [#2850](https://github.com/plotly/dash/issues/2850) - [#2859](https://github.com/plotly/dash/pull/2859) Fix base patch operators. fixes [#2855](https://github.com/plotly/dash/issues/2855) +- [#2856](https://github.com/plotly/dash/pull/2856) Fix multiple consecutive calls with same id to set_props only keeping the last props. Fixes [#2852](https://github.com/plotly/dash/issues/2852) ## [2.17.0] - 2024-05-03