def _notify_trait(self, name, old_value, new_value):

        # First dynamic ones
        callables = self._trait_notifiers.get(name,[])
        more_callables = self._trait_notifiers.get('anytrait',[])
        callables.extend(more_callables)

        # Now static ones
        try:
            cb = getattr(self, '_%s_changed' % name)
        except:
            pass
        else:
            callables.append(cb)

        # Call them all now
        for c in callables:
            # Traits catches and logs errors here.  I allow them to raise
            if callable(c):
                argspec = inspect.getargspec(c)
                nargs = len(argspec[0])
                # Bound methods have an additional 'self' argument
                # I don't know how to treat unbound methods, but they
                # can't really be used for callbacks.
                if isinstance(c, types.MethodType):
                    offset = -1
                else:
                    offset = 0
                if nargs + offset == 0:
                    c()
                elif nargs + offset == 1:
                    c(name)
                elif nargs + offset == 2:
                    c(name, new_value)
                elif nargs + offset == 3:
                    c(name, old_value, new_value)
                else:
                    raise TraitError('a trait changed callback '
                                        'must have 0-3 arguments.')
            else:
                raise TraitError('a trait changed callback '
                                    'must be callable.')
dataset/ETHPy150Open enthought/depsolver/depsolver/bundled/traitlets/_implementation.py/HasTraits._notify_trait/original