'Internal implementation helper to set property values.
This function handles bookkeeping around noting whether values have
been explicitly set, or setting up |PropertyContainer| wrappers when
values are containers, etc.
Args:
obj (HasProps)
The object the property is being set on.
old (obj) :
The previous value of the property to compare
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 _real_set(self, obj, old, value, hint=None, setter=None):

    unchanged = (self.property.matches(value, old) and (hint is None))
    if unchanged:
        return
    was_set = (self.name in obj._property_values)
    if was_set:
        old_attr_value = obj._property_values[self.name]
    else:
        old_attr_value = old
    if (old_attr_value is not value):
        if isinstance(old_attr_value, PropertyValueContainer):
            old_attr_value._unregister_owner(obj, self)
        if isinstance(value, PropertyValueContainer):
            value._register_owner(obj, self)
        if (self.name in obj._unstable_themed_values):
            del obj._unstable_themed_values[self.name]
        if (self.name in obj._unstable_default_values):
            del obj._unstable_default_values[self.name]
        obj._property_values[self.name] = value
    self._trigger(obj, old, value, hint, setter)
