From 748dcd733eb3080a5736ca65cfc1c1e195ff45c6 2014-08-11 18:36:59
From: Jason Grout <jgrout6@bloomberg.net>
Date: 2014-08-11 18:36:59
Subject: [PATCH] Make the widget comm attribute more straigtforward

Instead of automagically instantiating a comm when it is accessed, require a call to open().  This makes the comm attribute much less magical, and hopefully more understandable.

---

diff --git a/IPython/html/widgets/widget.py b/IPython/html/widgets/widget.py
index 2107f21..f9ee5fc 100644
--- a/IPython/html/widgets/widget.py
+++ b/IPython/html/widgets/widget.py
@@ -100,7 +100,7 @@ class Widget(LoggingConfigurable):
         registered in the front-end to create and sync this widget with.""")
     _view_name = Unicode(help="""Default view registered in the front-end
         to use to represent the widget.""", sync=True)
-    _comm = Instance('IPython.kernel.comm.Comm')
+    comm = Instance('IPython.kernel.comm.Comm')
     
     msg_throttle = Int(3, sync=True, help="""Maximum number of msgs the 
         front-end can send before receiving an idle msg from the back-end.""")
@@ -133,20 +133,12 @@ class Widget(LoggingConfigurable):
     # Properties
     #-------------------------------------------------------------------------
 
-    @property
-    def comm(self):
-        """Gets the Comm associated with this widget.
-
-        If a Comm doesn't exist yet, a Comm will be created automagically."""
-        self.open()
-        return self._comm
-    
     def open(self):
         """Open a comm to the frontend if one isn't already open."""
-        if self._comm is None:
+        if self.comm is None:
             # Create a comm.
-            self._comm = Comm(target_name=self._model_name)
-            self._comm.on_msg(self._handle_msg)
+            self.comm = Comm(target_name=self._model_name)
+            self.comm.on_msg(self._handle_msg)
             Widget.widgets[self.model_id] = self
 
             # first update
@@ -169,10 +161,10 @@ class Widget(LoggingConfigurable):
         Closes the underlying comm.
         When the comm is closed, all of the widget views are automatically
         removed from the front-end."""
-        if self._comm is not None:
+        if self.comm is not None:
             Widget.widgets.pop(self.model_id, None)
-            self._comm.close()
-        self._comm = None
+            self.comm.close()
+            self.comm = None
     
     def send_state(self, key=None):
         """Sends the widget state, or a piece of it, to the front-end.
@@ -393,7 +385,10 @@ class DOMWidget(Widget):
         selector: unicode (optional, kwarg only)
             JQuery selector to use to apply the CSS key/value.  If no selector 
             is provided, an empty selector is used.  An empty selector makes the 
-            front-end try to apply the css to the top-level element.
+            front-end try to apply the css to a default element.  The default
+            element is an attribute unique to each view, which is a DOM element
+            of the view that should be styled with common CSS (see 
+            `$el_to_style` in the Javascript code).
         """
         if value is None:
             css_dict = dict_or_key