Skip to content

Commit 3a207ce

Browse files
committed
Merge branch 'dev' into long-callback-errors
2 parents 9509213 + 760af72 commit 3a207ce

File tree

8 files changed

+45
-71
lines changed

8 files changed

+45
-71
lines changed

CHANGELOG.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@
22
All notable changes to `dash` will be documented in this file.
33
This project adheres to [Semantic Versioning](https://semver.org/).
44

5-
## Unreleased
5+
## [2.5.1] - 2022-06-13
66

77
### Fixed
8+
9+
- [#2087](https://github.com/plotly/dash/pull/2087) Fix bug [#2086](https://github.com/plotly/dash/issues/2086) in which using id as a key within a component's id breaks the new callback context's `args_grouping` function.
810
- [#2084](https://github.com/plotly/dash/pull/2084) In dash 2.5.0, a default viewport meta tag was added as recommended for mobile-optimized sites by [mdn](https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag)
911
This feature can be disabled by providing an empty viewport meta tag. e.g. `app = Dash(meta_tags=[{"name": "viewport"}])`
12+
- [#2090](https://github.com/plotly/dash/pull/2090), [#2092](https://github.com/plotly/dash/pull/2092). Fixed bug where the `path` to the `pages_folder` was incorrect on Windows.
13+
14+
### Removed
15+
16+
- [#2087](https://github.com/plotly/dash/pull/2087) Removed the undocumented callback context `args_grouping_values` property which was incompatible with pattern-matching callbacks.
1017

1118
## [2.5.0] - 2022-06-07
1219

1320
### Added
1421

1522
- [#1947](https://github.com/plotly/dash/pull/1947) Added `pages` - a better way to build multi-page apps. For more information see the [forum post.](https://community.plotly.com/t/introducing-dash-pages-a-dash-2-x-feature-preview/57775)
1623
- [#1965](https://github.com/plotly/dash/pull/1965) Add component as props.
17-
- [#2049](https://github.com/plotly/dash/pull/2043) Added `wait_for_class_to_equal` and `wait_for_contains_class` methods to `dash.testing`
24+
- [#2049](https://github.com/plotly/dash/pull/2049) Added `wait_for_class_to_equal` and `wait_for_contains_class` methods to `dash.testing`
1825

1926
### Changed
2027

dash/_callback_context.py

+2-55
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import functools
22
import warnings
33
import json
4-
from copy import deepcopy
54
import flask
65

76
from . import exceptions
8-
from ._utils import stringify_id, AttributeDict
7+
from ._utils import AttributeDict
98

109

1110
def has_context(func):
@@ -147,59 +146,7 @@ def display(btn1, btn2):
147146
return "No clicks yet"
148147
149148
"""
150-
triggered = getattr(flask.g, "triggered_inputs", [])
151-
triggered = [item["prop_id"] for item in triggered]
152-
grouping = getattr(flask.g, "args_grouping", {})
153-
154-
def update_args_grouping(g):
155-
if isinstance(g, dict) and "id" in g:
156-
str_id = stringify_id(g["id"])
157-
prop_id = f"{str_id}.{g['property']}"
158-
159-
new_values = {
160-
"value": g.get("value"),
161-
"str_id": str_id,
162-
"triggered": prop_id in triggered,
163-
"id": AttributeDict(g["id"])
164-
if isinstance(g["id"], dict)
165-
else g["id"],
166-
}
167-
g.update(new_values)
168-
169-
def recursive_update(g):
170-
if isinstance(g, (tuple, list)):
171-
for i in g:
172-
update_args_grouping(i)
173-
recursive_update(i)
174-
if isinstance(g, dict):
175-
for i in g.values():
176-
update_args_grouping(i)
177-
recursive_update(i)
178-
179-
recursive_update(grouping)
180-
181-
return grouping
182-
183-
# todo not sure whether we need this, but it removes a level of nesting so
184-
# you don't need to use `.value` to get the value.
185-
@property
186-
@has_context
187-
def args_grouping_values(self):
188-
grouping = getattr(flask.g, "args_grouping", {})
189-
grouping = deepcopy(grouping)
190-
191-
def recursive_update(g):
192-
if isinstance(g, (tuple, list)):
193-
for i in g:
194-
recursive_update(i)
195-
if isinstance(g, dict):
196-
for k, v in g.items():
197-
if isinstance(v, dict) and "id" in v:
198-
g[k] = v["value"]
199-
recursive_update(v)
200-
201-
recursive_update(grouping)
202-
return grouping
149+
return getattr(flask.g, "args_grouping", [])
203150

204151
@property
205152
@has_context

dash/_grouping.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
1515
"""
1616
from dash.exceptions import InvalidCallbackReturnValue
17-
from ._utils import AttributeDict
17+
from ._utils import AttributeDict, stringify_id
1818

1919

2020
def flatten_grouping(grouping, schema=None):
@@ -222,3 +222,17 @@ def validate_grouping(grouping, schema, full_schema=None, path=()):
222222
)
223223
else:
224224
pass
225+
226+
227+
def update_args_group(g, triggered):
228+
if isinstance(g, dict):
229+
str_id = stringify_id(g["id"])
230+
prop_id = f"{str_id}.{g['property']}"
231+
232+
new_values = {
233+
"value": g.get("value"),
234+
"str_id": str_id,
235+
"triggered": prop_id in triggered,
236+
"id": AttributeDict(g["id"]) if isinstance(g["id"], dict) else g["id"],
237+
}
238+
g.update(new_values)

dash/_pages.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def _module_name_to_page_name(filename):
6161
def _infer_path(filename, template):
6262
if template is None:
6363
if CONFIG.pages_folder:
64-
pages_folder = CONFIG.pages_folder.split("/")[-1]
64+
pages_folder = CONFIG.pages_folder.replace("\\", "/").split("/")[-1]
6565
path = (
6666
filename.replace("_", "-")
6767
.replace(".", "/")

dash/dash.py

+12-6
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@
6161
from . import _watch
6262
from . import _get_app
6363

64-
from ._grouping import (
65-
flatten_grouping,
66-
map_grouping,
67-
grouping_len,
68-
)
64+
from ._grouping import flatten_grouping, map_grouping, grouping_len, update_args_group
6965

7066
from . import _pages
7167
from ._pages import (
@@ -1479,6 +1475,14 @@ def dispatch(self):
14791475
inputs_state = inputs + state
14801476
inputs_state = convert_to_AttributeDict(inputs_state)
14811477

1478+
# update args_grouping attributes
1479+
for g in inputs_state:
1480+
# check for pattern matching: list of inputs or state
1481+
if isinstance(g, list):
1482+
for pattern_match_g in g:
1483+
update_args_group(pattern_match_g, changed_props)
1484+
update_args_group(g, changed_props)
1485+
14821486
args_grouping = map_grouping(
14831487
lambda ind: inputs_state[ind], inputs_state_indices
14841488
)
@@ -2219,7 +2223,9 @@ def _import_layouts_from_pages(self):
22192223
continue
22202224

22212225
page_filename = os.path.join(root, file).replace("\\", "/")
2222-
_, _, page_filename = page_filename.partition(walk_dir + "/")
2226+
_, _, page_filename = page_filename.partition(
2227+
walk_dir.replace("\\", "/") + "/"
2228+
)
22232229
page_filename = page_filename.replace(".py", "").replace("/", ".")
22242230

22252231
pages_folder = (

dash/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.5.0"
1+
__version__ = "2.5.1"

tests/assets/grouping_app.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def grouping_app():
3939
),
4040
dict(
4141
items=dict(
42-
all=State({"item": ALL}, "children"),
42+
all=State({"id": ALL}, "children"),
4343
new=State("new-item", "value"),
4444
),
4545
triggers=[Input("add", "n_clicks"), Input("new-item", "n_submit")],
@@ -64,11 +64,11 @@ def edit_list(items, triggers):
6464
html.Div(
6565
[
6666
dcc.Checklist(
67-
id={"item": i, "action": "done"},
67+
id={"id": i, "property": "done"},
6868
options=[{"label": "", "value": "done"}],
6969
style={"display": "inline"},
7070
),
71-
html.Div(text, id={"item": i}, style=style_todo),
71+
html.Div(text, id={"id": i}, style=style_todo),
7272
],
7373
style={"clear": "both"},
7474
)

tests/integration/callbacks/test_wildcards.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,10 @@ def assert_callback_context(items_text):
421421
items=dict(
422422
all=[
423423
{
424-
"id": {"item": i},
424+
"id": {"id": i},
425425
"property": "children",
426426
"value": text,
427-
"str_id": stringify_id({"item": i}),
427+
"str_id": stringify_id({"id": i}),
428428
"triggered": False,
429429
}
430430
for i, text in enumerate(items_text[:-1])

0 commit comments

Comments
 (0)