Skip to content

Commit 4c376b8

Browse files
authored
Improve error message on components with invalid prop names (#1074)
1 parent ee35164 commit 4c376b8

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
66

77
### Changed
88
- [#1035](https://github.com/plotly/dash/pull/1035) Simplify our build process.
9+
- [#1074](https://github.com/plotly/dash/pull/1045) Error messages when providing an incorrect property to a component have been improved: they now specify the component type, library, version, and ID (if available).
910

1011
### Fixed
1112
- [#1037](https://github.com/plotly/dash/pull/1037) Fix no_update test to allow copies, such as those stored and retrieved from a cache.

Diff for: dash/development/base_component.py

+24-4
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,38 @@ def __init__(self, **kwargs):
8686
k_in_wildcards = any(
8787
[k.startswith(w) for w in self._valid_wildcard_attributes]
8888
)
89+
# e.g. "The dash_core_components.Dropdown component (version 1.6.0)
90+
# with the ID "my-dropdown"
91+
try:
92+
error_string_prefix = 'The `{}.{}` component (version {}){}'.format(
93+
self._namespace,
94+
self._type,
95+
getattr(__import__(self._namespace), '__version__', 'unknown'),
96+
' with the ID "{}"'.format(kwargs['id'])
97+
if 'id' in kwargs else ''
98+
)
99+
except ImportError:
100+
# Our tests create mock components with libraries that
101+
# aren't importable
102+
error_string_prefix = 'The `{}` component{}'.format(
103+
self._type,
104+
' with the ID "{}"'.format(kwargs['id'])
105+
if 'id' in kwargs else ''
106+
)
107+
89108
if not k_in_propnames and not k_in_wildcards:
90109
raise TypeError(
91-
"Unexpected keyword argument `{}`".format(k)
92-
+ "\nAllowed arguments: {}".format(
93-
# pylint: disable=no-member
110+
"{} received an unexpected keyword argument: `{}`".format(
111+
error_string_prefix, k
112+
) + "\nAllowed arguments: {}".format( # pylint: disable=no-member
94113
", ".join(sorted(self._prop_names))
95114
)
96115
)
97116

98117
if k != "children" and isinstance(v, Component):
99118
raise TypeError(
100-
"Component detected as a prop other than `children`\n" +
119+
error_string_prefix +
120+
" detected a Component for a prop other than `children`\n" +
101121
"Did you forget to wrap multiple `children` in an array?\n" +
102122
"Prop {} has value {}\n".format(k, repr(v))
103123
)

Diff for: tests/unit/development/test_base_component.py

+43
Original file line numberDiff line numberDiff line change
@@ -435,3 +435,46 @@ def test_debc026_component_not_children():
435435
with pytest.raises(TypeError):
436436
# If you forget the `[]` around children you get this:
437437
html.Div(children[0], children[1], children[2], children[3])
438+
439+
440+
def test_debc027_component_error_message():
441+
with pytest.raises(TypeError) as e:
442+
Component(asdf=True)
443+
assert str(e.value) == (
444+
"The `TestComponent` component received an unexpected " +
445+
"keyword argument: `asdf`\nAllowed arguments: a, children, " +
446+
"id, style"
447+
)
448+
449+
with pytest.raises(TypeError) as e:
450+
Component(asdf=True, id='my-component')
451+
assert str(e.value) == (
452+
"The `TestComponent` component " +
453+
"with the ID \"my-component\" received an unexpected " +
454+
"keyword argument: `asdf`\nAllowed arguments: a, children, " +
455+
"id, style"
456+
)
457+
458+
with pytest.raises(TypeError) as e:
459+
html.Div(asdf=True)
460+
assert str(e.value) == (
461+
"The `dash_html_components.Div` component " +
462+
"(version {}) ".format(html.__version__) +
463+
"received an unexpected " +
464+
"keyword argument: `asdf`\n" +
465+
"Allowed arguments: {}".format(
466+
', '.join(sorted(html.Div()._prop_names))
467+
)
468+
)
469+
470+
with pytest.raises(TypeError) as e:
471+
html.Div(asdf=True, id='my-component')
472+
assert str(e.value) == (
473+
"The `dash_html_components.Div` component " +
474+
"(version {}) ".format(html.__version__) +
475+
"with the ID \"my-component\" received an unexpected " +
476+
"keyword argument: `asdf`\n" +
477+
"Allowed arguments: {}".format(
478+
', '.join(sorted(html.Div()._prop_names))
479+
)
480+
)

0 commit comments

Comments
 (0)