From 0e5ceca059995091d5ef07af4f3b93625f90befc Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Mon, 18 Aug 2014 17:28:07 +0000 Subject: [PATCH] Make the widget property_lock store the JSON state, not the original object Comparison between arbitrary python objects can get crazy, whereas we really only care about if the JSON state we are syncing is different. So with this change, we store and check against the JSON state. --- IPython/html/widgets/widget.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/IPython/html/widgets/widget.py b/IPython/html/widgets/widget.py index f39c75469..98f49d5d3 100644 --- a/IPython/html/widgets/widget.py +++ b/IPython/html/widgets/widget.py @@ -202,9 +202,7 @@ class Widget(LoggingConfigurable): raise ValueError("key must be a string, an iterable of keys, or None") state = {} for k in keys: - f = self.trait_metadata(k, 'to_json') - if f is None: - f = self._trait_to_json + f = self.trait_metadata(k, 'to_json', self._trait_to_json) value = getattr(self, k) state[k] = f(value) return state @@ -255,6 +253,8 @@ class Widget(LoggingConfigurable): def _lock_property(self, key, value): """Lock a property-value pair. + The value should be the JSON state of the property. + NOTE: This, in addition to the single lock for all state changes, is flawed. In the future we may want to look into buffering state changes back to the front-end.""" @@ -280,7 +280,9 @@ class Widget(LoggingConfigurable): def _should_send_property(self, key, value): """Check the property lock (property_lock)""" - if (key == self._property_lock[0] and value == self._property_lock[1]): + to_json = self.trait_metadata(key, 'to_json', self._trait_to_json) + if (key == self._property_lock[0] + and to_json(value) == self._property_lock[1]): return False elif self._send_state_lock > 0: self._states_to_send.add(key) @@ -311,12 +313,10 @@ class Widget(LoggingConfigurable): """Called when a state is received from the front-end.""" for name in self.keys: if name in sync_data: - f = self.trait_metadata(name, 'from_json') - if f is None: - f = self._trait_from_json - value = f(sync_data[name]) - with self._lock_property(name, value): - setattr(self, name, value) + json_value = sync_data[name] + from_json = self.trait_metadata(name, 'from_json', self._trait_from_json) + with self._lock_property(name, json_value): + setattr(self, name, from_json(json_value)) def _handle_custom_msg(self, content): """Called when a custom msg is received."""