Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

dcc.Checklist() gives error loading layout #440

Closed
T4rk1n opened this issue Jan 19, 2019 · 4 comments · Fixed by plotly/dash#753
Closed

dcc.Checklist() gives error loading layout #440

T4rk1n opened this issue Jan 19, 2019 · 4 comments · Fixed by plotly/dash#753
Labels
dash-type-bug Something isn't working as intended

Comments

@T4rk1n
Copy link
Contributor

T4rk1n commented Jan 19, 2019

A dcc.Checklist in the layout results in error loading layout:

app.layout = html.Div([
    dcc.Checklist(),
])

Stack trace:

"GET /_dash-layout HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/dash/dash.py", line 317, in serve_layout
    cls=plotly.utils.PlotlyJSONEncoder),
  File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/plotly/utils.py", line 168, in encode
    encoded_o = super(PlotlyJSONEncoder, self).encode(o)
  File "/usr/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/home/t4rk/Projects/dash_dev/pytest-dash/venv/lib/python3.6/site-packages/plotly/utils.py", line 236, in default
    return _json.JSONEncoder.default(self, obj)
  File "/usr/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'method' is not JSON serializable
(venv) t4rk@stone:~/Projects/dash_dev/pytest-dash$ pip freeze | grep dash
dash==0.35.2
dash-core-components==0.42.1
dash-html-components==0.13.2
dash-renderer==0.15.1
@T4rk1n T4rk1n added the dash-type-bug Something isn't working as intended label Jan 19, 2019
@tmbluth
Copy link

tmbluth commented May 28, 2019

I am having the same trouble while trying to populate a checklist depending on user input from a dropdown. I don't think it's the way I've set up the code since changing the component to another Dropdown allows it to work just fine

@alexcjohnson
Copy link
Collaborator

Thanks for bringing this one back up @tmbluth. The issue is something about omitting the values field. While we investigate, if you provide it initially as values=[] it should work.

BTW just a heads up - in the next version of dash we're planning to change values to value anyway - even though it's an array, value is more consistent with other items - like Dropdown, where value can be either an array or a single value depending on its multi prop.

@alexcjohnson
Copy link
Collaborator

As it turns out, values is a method of collections(.abc).MutableMapping, so if you don't provide a value for it, it keeps the original; but then since it matches an attribute name we try to serialize the method into the layout and it fails. (note: we have two serializations to fix this in: to_plotly_json and __repr__)

So in fact the immediate problem here will go away when we switch from values to value. But we'll need something more robust to prevent similar things from happening again.

We could fix serialization just by skipping any props inherited from the base Component class (perhaps by deriving the whole serialization from __dict__, which we have to iterate over anyway, rather than using getattr for everything in _prop_names).

But if that's all we do, we could still be vulnerable to more subtle bugs if anyone actually wants to use these inherited methods, and fatal bugs if someone made a component with a property like to_plotly_json, available_properties, or __dict__.

So what's the right way to handle this? Blacklist all the attribute names we use in Python? Possible, but who's to say we won't need to add to that list when we add another language (cc @rpkyle). We could make it easier by blacklisting leading underscores (would that be a problem for any of our existing components? Would we be worried about this for 3rd-party components?) but we'd still have all these:

# from MutableMapping
clear
get
items
keys
pop
popitem
setdefault
update
values

# from base_component.Component
REQUIRED
UNDEFINED
to_plotly_json
traverse
traverse_with_paths

TBH it's not clear to me how we benefit from Component inheriting from MutableMapping - we don't seem to be using the mixin methods above, and we can implement the magic methods that help access the children property without MutableMapping telling us to. Can we drop that? And we could easily add underscores to traverse(_with_paths), which would leave us just with REQUIRED, UNDEFINED, and to_plotly_json - a much more manageable blacklist.

@alexcjohnson
Copy link
Collaborator

Oh also available_properties and available_wildcard_properties - these we can't underscore so easily because they're defined in the individual components' __init__ methods, so they should probably go in the blacklist too.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
dash-type-bug Something isn't working as intended
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants