-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Update graph reference #292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
793bfa9
3b2d398
92e6e4f
98e8bc9
e38daa4
248fa95
729a0bb
1963dcb
c1ba309
b129039
84d7ca3
a21fe90
bd01684
e747302
a90a922
69b868f
3543781
59a703e
f3495e5
f8610e3
45729be
e46276a
b421c35
6d27008
e8b342e
06be891
687969e
9f27eba
7dcfc96
d338502
50184c9
e96ffc7
1dd6035
d961a7a
52b9d0d
84fe0d6
514a3ee
c997773
08a76c7
3a715c6
cc62571
59c12c7
a79dbf4
42f450c
ecc267d
aa2da24
a0ae2a2
801d81d
8920dc2
ace9f68
b434a3c
8d31b6e
2649be7
3fd16ba
3615088
d653001
fbdd9e8
0d34997
b2fa961
96c226a
f9edd67
a31dbd5
fca4d5f
de24bd8
8ed7f81
80d17e1
4950915
5e6b465
56100a7
8049439
45b3fc7
4f610fc
301f21d
f8dc6a3
992a73a
eccb469
8fc79ff
c12fc2c
7a24734
1f84f23
2131e98
496242d
e387a16
4bd19d4
4320ce4
3edbe08
0ed1c98
79132b3
7b01986
35224f6
80fa6c9
f4beea0
d207577
9cfa817
6e80023
c215ab8
91c51e4
211f46c
97c8801
dcf6d45
bda1c93
924f181
0be0d20
033e8dd
691bf73
41e9675
1b0f007
02adc54
4f65904
00c1f83
fa3e928
19be9ab
d315065
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Auto-complete sub-attrs. Keep things converted to graph objs *always*. `__setitem__` is again the most important thing to look at! Note that `__missing__` isn’t actually inherited, but exists in `defaultdict`. Instead of inheriting from *that*, we just copy the idea. Basically, this gets called when an attr or key can’t be found on the object. It’s what does the auto-creation of things that don’t exist yet. Also note the `__dir__` function which allows dynamic listing of *possible* attributes on PlotlyDict objects. This is especially nice in IPython Notebooks where you can just hit `TAB`.
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -355,28 +355,97 @@ class PlotlyDict(dict, PlotlyBase): | |
| _parent_key = None | ||
|
|
||
| def __init__(self, *args, **kwargs): | ||
| class_name = self.__class__.__name__ | ||
|
|
||
| for key in kwargs: | ||
| if utils.is_source_key(key): | ||
| kwargs[key] = self._assign_id_to_src(key, kwargs[key]) | ||
|
|
||
| super(PlotlyDict, self).__init__(*args, **kwargs) | ||
| if issubclass(NAME_TO_CLASS[class_name], PlotlyTrace): | ||
| if (class_name != 'PlotlyTrace') and (class_name != 'Trace'): | ||
| self['type'] = NAME_TO_KEY[class_name] | ||
| self.validate() | ||
| if self.__class__.__name__ == 'PlotlyDict': | ||
| warnings.warn("\nThe PlotlyDict class is a base class of " | ||
| "dictionary-like graph_objs.\nIt is not meant to be " | ||
| "a user interface.") | ||
| if self._name is None: | ||
| raise exceptions.PlotlyError( | ||
| "PlotlyDict is a base class. It's shouldn't be instantiated." | ||
| ) | ||
|
|
||
| _raise = kwargs.pop('_raise', True) | ||
|
|
||
| super(PlotlyDict, self).__init__() | ||
|
|
||
| if self._name in graph_reference.TRACE_NAMES: | ||
| self['type'] = self._name | ||
|
|
||
| # force key-value pairs to go through validation | ||
| d = {key: val for key, val in dict(*args, **kwargs).items()} | ||
| for key, val in d.items(): | ||
| try: | ||
| self.__setitem__(key, val, _raise=_raise) | ||
| except exceptions.PlotlyGraphObjectError as err: | ||
| err.prepare() | ||
| raise | ||
|
|
||
| def __dir__(self): | ||
| attrs = self.__dict__.keys() | ||
| attrs += [attr for attr in dir(dict()) if attr not in attrs] | ||
| return sorted(self._attributes) + attrs | ||
|
|
||
| def __getitem__(self, key): | ||
| if key not in self: | ||
| self.__missing__(key) | ||
| return super(PlotlyDict, self).__getitem__(key) | ||
|
|
||
| def __setattr__(self, key, value): | ||
| self.__setitem__(key, value) | ||
|
|
||
| def __setitem__(self, key, value): | ||
| def __setitem__(self, key, value, _raise=True): | ||
|
|
||
| if key in ('xsrc', 'ysrc'): | ||
| value = self._assign_id_to_src(key, value) | ||
| if not isinstance(key, six.string_types): | ||
| if _raise: | ||
| raise TypeError('Key must be string, not {}'.format(type(key))) | ||
| return | ||
|
|
||
| if key.endswith('src') and key in self._attributes: | ||
| value = graph_objs_tools.assign_id_to_src(key, value) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @chriddyp ? i believe this is something he added a while back, just maintaining. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. great, thanks There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, something weird w grid_objs |
||
| return super(PlotlyDict, self).__setitem__(key, value) | ||
|
|
||
| return super(PlotlyDict, self).__setitem__(key, value) | ||
| subplot_key = self._get_subplot_key(key) | ||
| if subplot_key is not None: | ||
| value = self.value_to_graph_object(subplot_key, value, | ||
| _raise=_raise) | ||
| if isinstance(value, (PlotlyDict, PlotlyList)): | ||
| value.__dict__['_parent'] = self | ||
| value.__dict__['_parent_key'] = key | ||
| return super(PlotlyDict, self).__setitem__(key, value) | ||
|
|
||
| if key not in self._attributes: | ||
| if _raise: | ||
| raise exceptions.PlotlyDictKeyError(self, key) | ||
| return | ||
|
|
||
| if graph_objs_tools.get_role(self, key) == 'object': | ||
| value = self.value_to_graph_object(key, value, _raise=_raise) | ||
| if isinstance(value, (PlotlyDict, PlotlyList)): | ||
| value.__dict__['_parent'] = self | ||
| value.__dict__['_parent_key'] = key | ||
| else: | ||
| return | ||
|
|
||
| super(PlotlyDict, self).__setitem__(key, value) | ||
|
|
||
| def __getattr__(self, key): | ||
| """Python only calls this when key is missing!""" | ||
| try: | ||
| return self.__getitem__(key) | ||
| except KeyError: | ||
| raise AttributeError(key) | ||
|
|
||
| def __missing__(self, key): | ||
|
|
||
| if key in self._attributes: | ||
| if graph_objs_tools.get_role(self, key) == 'object': | ||
| value = GraphObjectFactory.create(key) | ||
| value.__dict__['_parent'] = self | ||
| value.__dict__['_parent_key'] = key | ||
| return super(PlotlyDict, self).__setitem__(key, value) | ||
|
|
||
| subplot_key = self._get_subplot_key(key) | ||
| if subplot_key is not None: | ||
| value = GraphObjectFactory.create(subplot_key) | ||
| value.__dict__['_parent'] = self | ||
| value.__dict__['_parent_key'] = key | ||
| super(PlotlyDict, self).__setitem__(key, value) | ||
|
|
||
| def _get_subplot_key(self, key): | ||
|
|
||
|
|
||