##// END OF EJS Templates
Implement a context manager as a property locking mechanism in Widget.
Jonathan Frederic -
Show More
@@ -14,6 +14,7 b' in the IPython notebook frontend.'
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 from copy import copy
15 from copy import copy
16 from glob import glob
16 from glob import glob
17 from contextlib import contextmanager
17 import uuid
18 import uuid
18 import sys
19 import sys
19 import os
20 import os
@@ -30,6 +31,17 b' from IPython.utils.py3compat import string_types'
30 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
31 # Classes
32 # Classes
32 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 @contextmanager
35 def PropertyLock(instance, key, value):
36 instance._property_lock = (key, value)
37 yield
38 del instance._property_lock
39
40 def should_send_property(instance, key, value):
41 return not hasattr(instance, _property_lock) or \
42 key != instance._property_lock[0] or \
43 value != instance._property_lock[1]
44
33
45
34 class Widget(LoggingConfigurable):
46 class Widget(LoggingConfigurable):
35
47
@@ -58,8 +70,6 b' class Widget(LoggingConfigurable):'
58 to use to represent the widget.""")
70 to use to represent the widget.""")
59
71
60 # Private/protected declarations
72 # Private/protected declarations
61 # todo: change this to a context manager
62 _property_lock = (None, None) # Last updated (key, value) from the front-end. Prevents echo.
63 _comm = Instance('IPython.kernel.comm.Comm')
73 _comm = Instance('IPython.kernel.comm.Comm')
64
74
65 def __init__(self, **kwargs):
75 def __init__(self, **kwargs):
@@ -114,11 +124,9 b' class Widget(LoggingConfigurable):'
114 """Called when a state is recieved from the frontend."""
124 """Called when a state is recieved from the frontend."""
115 for name in self.keys:
125 for name in self.keys:
116 if name in sync_data:
126 if name in sync_data:
117 try:
127 value = sync_data[name]
118 self._property_lock = (name, sync_data[name])
128 with PropertyLock(self, name, value):
119 setattr(self, name, sync_data[name])
129 setattr(self, name, value)
120 finally:
121 self._property_lock = (None, None)
122
130
123
131
124 def _handle_custom_msg(self, content):
132 def _handle_custom_msg(self, content):
@@ -145,7 +153,7 b' class Widget(LoggingConfigurable):'
145 def _handle_property_changed(self, name, old, new):
153 def _handle_property_changed(self, name, old, new):
146 """Called when a property has been changed."""
154 """Called when a property has been changed."""
147 # Make sure this isn't information that the front-end just sent us.
155 # Make sure this isn't information that the front-end just sent us.
148 if self._property_lock[0] != name and self._property_lock[1] != new:
156 if should_send_property(self, name, new):
149 # Send new state to frontend
157 # Send new state to frontend
150 self.send_state(key=name)
158 self.send_state(key=name)
151
159
General Comments 0
You need to be logged in to leave comments. Login now