From dd24cb91cceba48e4d6b7f54ae66f3479cb76140 Mon Sep 17 00:00:00 2001 From: philippe Date: Mon, 15 Jul 2024 09:59:57 -0400 Subject: [PATCH 1/6] Fix background callback hash_function --- dash/long_callback/managers/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dash/long_callback/managers/__init__.py b/dash/long_callback/managers/__init__.py index 6167828c60..5bfdc837bc 100644 --- a/dash/long_callback/managers/__init__.py +++ b/dash/long_callback/managers/__init__.py @@ -107,8 +107,11 @@ def _make_set_props_key(key): @staticmethod def hash_function(fn, callback_id=""): - fn_source = inspect.getsource(fn) - fn_str = fn_source + try: + fn_source = inspect.getsource(fn) + fn_str = fn_source + except OSError: # pylint: disable=too-broad-exception + fn_str = getattr(fn, "__name__", "") return hashlib.sha256( callback_id.encode("utf-8") + fn_str.encode("utf-8") ).hexdigest() From e75f3006b7af1fe1ffdea9a3c0afd64fce9ea1f5 Mon Sep 17 00:00:00 2001 From: philippe Date: Mon, 15 Jul 2024 10:01:24 -0400 Subject: [PATCH 2/6] Fix error handler NoUpdate call --- dash/_callback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/_callback.py b/dash/_callback.py index 0c7476fda1..4ab03f364d 100644 --- a/dash/_callback.py +++ b/dash/_callback.py @@ -507,7 +507,7 @@ def add_context(*args, **kwargs): if not multi: output_value = NoUpdate() else: - output_value = [NoUpdate for _ in output_spec] + output_value = [NoUpdate() for _ in output_spec] else: raise err From ad7ed2ec34a5e30e8f2f537ad59e7dcb6d54a596 Mon Sep 17 00:00:00 2001 From: philippe Date: Mon, 15 Jul 2024 10:22:25 -0400 Subject: [PATCH 3/6] Update changelog. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb27c8d71..b26066a128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## Added - [#2881](https://github.com/plotly/dash/pull/2881) Add outputs_list to window.dash_clientside.callback_context. Fixes [#2877](https://github.com/plotly/dash/issues/2877). +- [#2903](https://github.com/plotly/dash/pull/2903) Add callback on_error handler, either globally on Dash init or per callback basis. Receives the exception as first argument, can return output(s) or None for `no_update`. Access to original callback context is preserved and `set_props` works inside the error handler. ## Fixed @@ -15,6 +16,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). - [#2896](https://github.com/plotly/dash/pull/2896) The tabIndex parameter of Div can accept number or string type. Fixes [#2891](https://github.com/plotly/dash/issues/2891) - [#2900](https://github.com/plotly/dash/pull/2900) Allow strings in layout list. Fixes [#2890](https://github.com/plotly/dash/issues/2890) - [#2908](https://github.com/plotly/dash/pull/2908) Fix when environment variables are ignored by Dash.run() at runtime. Fixes [#2902](https://github.com/plotly/dash/issues/2902) +- [#2888](https://github.com/plotly/dash/pull/2888) Add id to dcc.Loading DOM. Fixes [#2878](https://github.com/plotly/dash/issues/2878) +- [#2922](https://github.com/plotly/dash/pull/2922) Fix background callback hash_function when source is unavailable. Fixes [#1885](https://github.com/plotly/dash/issues/1885) ## [2.17.1] - 2024-06-12 From 9744a684ceea4695366835edd02e903eea134acf Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 28 Aug 2024 08:52:15 -0400 Subject: [PATCH 4/6] Set arb003 flaky --- tests/integration/callbacks/test_arbitrary_callbacks.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/integration/callbacks/test_arbitrary_callbacks.py b/tests/integration/callbacks/test_arbitrary_callbacks.py index 4a49dba249..7a9849e2bd 100644 --- a/tests/integration/callbacks/test_arbitrary_callbacks.py +++ b/tests/integration/callbacks/test_arbitrary_callbacks.py @@ -11,6 +11,8 @@ clientside_callback, ) +from flaky import flaky + def test_arb001_global_set_props(dash_duo): app = Dash() @@ -89,6 +91,7 @@ def no_output3(_): assert counter.value == 1 +@flaky(max_runs=3) def test_arb003_arbitrary_pages(dash_duo): app = Dash(use_pages=True, pages_folder="") From d99da2a374e6e151ef136edb870bc78a0dd0c08e Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 28 Aug 2024 09:28:28 -0400 Subject: [PATCH 5/6] Add clear_pages_state to arb003 --- tests/integration/callbacks/test_arbitrary_callbacks.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/integration/callbacks/test_arbitrary_callbacks.py b/tests/integration/callbacks/test_arbitrary_callbacks.py index 7a9849e2bd..f07afc08be 100644 --- a/tests/integration/callbacks/test_arbitrary_callbacks.py +++ b/tests/integration/callbacks/test_arbitrary_callbacks.py @@ -11,8 +11,6 @@ clientside_callback, ) -from flaky import flaky - def test_arb001_global_set_props(dash_duo): app = Dash() @@ -91,8 +89,7 @@ def no_output3(_): assert counter.value == 1 -@flaky(max_runs=3) -def test_arb003_arbitrary_pages(dash_duo): +def test_arb003_arbitrary_pages(dash_duo, clear_pages_state): app = Dash(use_pages=True, pages_folder="") register_page( From 3a179f42c10a78aab0084d4e8ed0c3b79cf51db2 Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 28 Aug 2024 09:31:09 -0400 Subject: [PATCH 6/6] Add more clear_pages_state --- tests/integration/test_integration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index 47010bd319..c779ac47d4 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -366,7 +366,7 @@ def render_content(tab): until(lambda: '"label": 3' in dash_duo.find_element("#graph2_info").text, timeout=3) -def test_inin027_multi_page_without_pages_folder(dash_duo): +def test_inin027_multi_page_without_pages_folder(dash_duo, clear_pages_state): app = Dash(__name__, pages_folder="") # test for storing arbitrary keyword arguments: An `id` prop is defined for every page @@ -473,7 +473,7 @@ def on_nested_click(n_clicks): dash_duo.wait_for_text_to_equal("#nested-output", "Clicked 1 times") -def test_inin029_layout_as_list_with_pages(dash_duo): +def test_inin029_layout_as_list_with_pages(dash_duo, clear_pages_state): app = Dash(use_pages=True, pages_folder="") dash.register_page(