Skip to content

Commit 354d1a0

Browse files
authored
Merge pull request #2987 from plotly/fix/num-no-output-2986
Fix multioutput requiring same number of no_update.
2 parents 5a98989 + 2495492 commit 354d1a0

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

Diff for: CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
44

55
## [UNRELEASED]
66

7+
## Fixed
8+
9+
- [#2987](https://github.com/plotly/dash/pull/2987) Fix multioutput requiring same number of no_update. Fixes [#2986](https://github.com/plotly/dash/issues/2986)
10+
711
## Deprecated
812

913
- [#2985](https://github.com/plotly/dash/pull/2985) Deprecate dynamic component loader.

Diff for: dash/_callback.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -528,12 +528,16 @@ def add_context(*args, **kwargs):
528528
# list or tuple
529529
output_value = list(output_value)
530530

531-
# Flatten grouping and validate grouping structure
532-
flat_output_values = flatten_grouping(output_value, output)
531+
if NoUpdate.is_no_update(output_value):
532+
flat_output_values = [output_value]
533+
else:
534+
# Flatten grouping and validate grouping structure
535+
flat_output_values = flatten_grouping(output_value, output)
533536

534-
_validate.validate_multi_return(
535-
output_spec, flat_output_values, callback_id
536-
)
537+
if not NoUpdate.is_no_update(output_value):
538+
_validate.validate_multi_return(
539+
output_spec, flat_output_values, callback_id
540+
)
537541

538542
for val, spec in zip(flat_output_values, output_spec):
539543
if NoUpdate.is_no_update(val):

Diff for: tests/integration/callbacks/test_missing_outputs.py

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import time
2+
13
import pytest
24
from multiprocessing import Lock, Value
35

46
import dash
5-
from dash import Dash, Input, Output, ALL, MATCH, html, dcc
7+
from dash import Dash, Input, Output, ALL, MATCH, html, dcc, no_update
68

79
from dash.testing.wait import until
810

@@ -336,3 +338,34 @@ def chapter2_assertions():
336338
dash_duo._wait_for_callbacks()
337339
chapter2_assertions()
338340
assert not dash_duo.get_logs()
341+
342+
343+
def test_cbmo005_no_update_single_to_multi(dash_duo):
344+
# Bugfix for #2986
345+
app = dash.Dash(__name__)
346+
347+
app.layout = html.Div(
348+
[
349+
dcc.Input(id="input-box", type="text", value=""),
350+
html.Button("Submit", id="button"),
351+
html.Div(id="output-1", children="Output 1 will be displayed here"),
352+
html.Div(id="output-2", children="Output 2 will be displayed here"),
353+
]
354+
)
355+
356+
@app.callback(
357+
Output("output-1", "children"),
358+
Output("output-2", "children"),
359+
Input("button", "n_clicks"),
360+
Input("input-box", "value"),
361+
)
362+
def update_outputs(n_clicks, value):
363+
if n_clicks is None:
364+
return no_update
365+
return "Hello", "world!"
366+
367+
dash_duo.start_server(app)
368+
369+
# just wait to make sure the error get logged.
370+
time.sleep(1)
371+
assert dash_duo.get_logs() == []

Diff for: tests/integration/renderer/test_dependencies.py

+3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
from dash import Dash, html, dcc, Input, Output
44

5+
from flaky import flaky
56

7+
8+
@flaky(max_runs=3)
69
def test_rddp001_dependencies_on_components_that_dont_exist(dash_duo):
710
app = Dash(__name__, suppress_callback_exceptions=True)
811
app.layout = html.Div(

0 commit comments

Comments
 (0)