Internal implementation helper to set property values.

        This function handles bookkeeping around noting whether values have
        been explicitly set, etc.

        Args:
            obj (HasProps)
                The object the property is being set on.

            old (obj) :
                The previous value of the property to compare

            hint (event hint or None, optional)
                An optional update event hint, e.g. ``ColumnStreamedEvent``
                (default: None)

                Update event hints are usually used at times when better
                update performance can be obtained by special-casing in
                some way (e.g. streaming or patching column data sources)

            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):
        ''' Internal implementation helper to set property values.

        This function handles bookkeeping around noting whether values have
        been explicitly set, etc.

        Args:
            obj (HasProps)
                The object the property is being set on.

            old (obj) :
                The previous value of the property to compare

            hint (event hint or None, optional)
                An optional update event hint, e.g. ``ColumnStreamedEvent``
                (default: None)

                Update event hints are usually used at times when better
                update performance can be obtained by special-casing in
                some way (e.g. streaming or patching column data sources)

            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

        '''
        # Normally we want a "no-op" if the new value and old value are identical
        # but some hinted events are in-place. This check will allow those cases
        # to continue on to the notification machinery
        if self.property.matches(value, old) and (hint is None):
            return

        was_set = self.name in obj._property_values

        # "old" is the logical old value, but it may not be the actual current
        # attribute value if our value was mutated behind our back and we got
        # _notify_mutated.
        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

        # for notification purposes, "old" should be the logical old
        self._trigger(obj, old, value, hint=hint, setter=setter)