'Implement the setter for the Python `descriptor protocol`_.
.. note::
An optional argument ``setter`` has been added to the standard
setter arguments. When needed, this value should be provided by
explicitly invoking ``__set__``. See below for more information.
Args:
obj (HasProps) :
The instance to set a new property value on
value (obj) :
The new value to set the property to
setter (ClientSession or ServerSession or None, optional) :
This is used to prevent "boomerang" updates to Bokeh apps.
(default: None)
In the context of a Bokeh server application, incoming updates
to properties will be annotated with the session that is
doing the updating. This value is propagated through any
subsequent change notifications that the update triggers.
The session can compare the event setter to itself, and
suppress any updates that originate from itself.
Returns:
None'

def __set__(self, obj, value, setter=None):

    if (not hasattr(obj, '_property_values')):
        raise RuntimeError(("Cannot    set    a    property    value    '%s'    on    a    %s    instance    before    HasProps.__init__" % (self.name, obj.__class__.__name__)))
    if self.property._readonly:
        raise RuntimeError(('%s.%s    is    a    readonly    property' % (obj.__class__.__name__, self.name)))
    self._internal_set(obj, value, setter)
