diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c0983e5c6..b42f438bc7 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. - [#2936](https://github.com/plotly/dash/pull/2936) Adds support for TypeScript 5.5+. - [#2789](https://github.com/plotly/dash/pull/2789) Add library loading capacity to `_allow_dynamic_callbacks` @@ -17,6 +18,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) - [#2915](https://github.com/plotly/dash/pull/2915) Fix 'AttributeError' when layout is a function that returns a list of components. Fixes [#2905](https://github.com/plotly/dash/issues/2905) - [#2956](https://github.com/plotly/dash/pull/2956) Add missing useEffect dependency to dcc.Loading component. diff --git a/dash/_callback.py b/dash/_callback.py index 5299151027..54a2e5a64c 100644 --- a/dash/_callback.py +++ b/dash/_callback.py @@ -512,7 +512,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 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() diff --git a/tests/integration/callbacks/test_arbitrary_callbacks.py b/tests/integration/callbacks/test_arbitrary_callbacks.py index 4a49dba249..f07afc08be 100644 --- a/tests/integration/callbacks/test_arbitrary_callbacks.py +++ b/tests/integration/callbacks/test_arbitrary_callbacks.py @@ -89,7 +89,7 @@ def no_output3(_): assert counter.value == 1 -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( 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(