Skip to content

Commit 41e322b

Browse files
committed
error when autogenerated IDs are used with persistence or snapshots
also give set_random_id a leading underscore so it doesn't need to become a reserved word (disallowed prop name)
1 parent 0f1b299 commit 41e322b

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

dash/dependencies.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DashDependency: # pylint: disable=too-few-public-methods
3030
def __init__(self, component_id, component_property):
3131

3232
if isinstance(component_id, Component):
33-
self.component_id = component_id.set_random_id()
33+
self.component_id = component_id._set_random_id()
3434
else:
3535
self.component_id = component_id
3636

dash/development/base_component.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,29 @@ def __init__(self, **kwargs):
167167

168168
setattr(self, k, v)
169169

170-
def set_random_id(self):
170+
def _set_random_id(self):
171+
if getattr(self, "persistence", False):
172+
raise RuntimeError(
173+
"""
174+
Attempting to use an auto-generated ID with the `persistence` prop.
175+
This is prohibited because persistence is tied to component IDs and
176+
auto-generated IDs can easily change.
177+
178+
Please assign an explicit ID to this component.
179+
"""
180+
)
181+
if "dash_snapshots" in sys.modules:
182+
raise RuntimeError(
183+
"""
184+
Attempting to use an auto-generated ID in an app with `dash_snapshots`.
185+
This is prohibited because snapshots saves the whole app layout,
186+
including component IDs, and auto-generated IDs can easily change.
187+
Callbacks referencing the new IDs will not work old snapshots.
188+
189+
Please assign an explicit ID to this component.
190+
"""
191+
)
192+
171193
if not hasattr(self, "id"):
172194
v = str(uuid.UUID(int=rd.randint(0, 2 ** 128)))
173195
setattr(self, "id", v)

dash/development/component_generator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"UNDEFINED",
2424
"REQUIRED",
2525
"to_plotly_json",
26-
"set_random_id",
2726
"available_properties",
2827
"available_wildcard_properties",
2928
"_.*",

tests/unit/development/test_base_component.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ def test_debc027_component_error_message():
476476
)
477477

478478

479-
def test_set_random_id():
479+
def test_debc028_set_random_id():
480480
app = Dash(__name__)
481481

482482
input1 = dcc.Input(value="Hello Input 1")
@@ -496,7 +496,7 @@ def update(v):
496496
return f"Input 2 {v}"
497497

498498
@app.callback(
499-
Output("output-3", "children"), Input(input1, "value"), Input(input2, "value")
499+
Output(output3, "children"), Input(input1, "value"), Input(input2, "value")
500500
)
501501
def update(v1, v2):
502502
return f"Output 3 - Input 1: {v1}, Input 2: {v2}"
@@ -508,3 +508,21 @@ def update(v1, v2):
508508
assert input2.id == "23a7711a-8133-2876-37eb-dcd9e87a1613"
509509
# we make sure that the if the id is set explicitly, then it is not replaced by random id
510510
assert output3.id == "output-3"
511+
512+
513+
def test_debc029_random_id_errors():
514+
app = Dash(__name__)
515+
516+
input1 = dcc.Input(value="Hello Input 1", persistence=True)
517+
output1 = html.Div()
518+
519+
app.layout = html.Div([input1, output1])
520+
521+
with pytest.raises(RuntimeError) as e:
522+
523+
@app.callback(Output(output1, "children"), Input(input1, "value"))
524+
def update(v):
525+
return f"Input 1 {v}"
526+
527+
assert "persistence" in e.value.args[0]
528+
assert "Please assign an explicit ID" in e.value.args[0]

0 commit comments

Comments
 (0)