Injects a function into an object as a method

    Wraps func as a bound method of self. Then injects func into self
    It is preferable to use make_class_method_decorator and inject_instance

    Args:
       self (object): class instance
       func : some function whos first arugment is a class instance
       method_name (str) : default=func.__name__, if specified renames the method
       class_ (type) : if func is an unbound method of this class


    References:
        http://stackoverflow.com/questions/1015307/python-bind-an-unbound-method

def inject_func_as_method(self, func, method_name=None, class_=None,
                          allow_override=False, allow_main=False,
                          verbose=True, override=None, force=False):
    """ Injects a function into an object as a method

    Wraps func as a bound method of self. Then injects func into self
    It is preferable to use make_class_method_decorator and inject_instance

    Args:
       self (object): class instance
       func : some function whos first arugment is a class instance
       method_name (str) : default=func.__name__, if specified renames the method
       class_ (type) : if func is an unbound method of this class


    References:
        http://stackoverflow.com/questions/1015307/python-bind-an-unbound-method
    """
    if override is not None:
        # TODO depcirate allow_override
        allow_override = override
    if method_name is None:
        method_name = get_funcname(func)
    if force:
        allow_override = True
        allow_main = True
    old_method = getattr(self, method_name, None)
    # Bind function to the class instance
    #new_method = types.MethodType(func, self, self.__class__)
    new_method = func.__get__(self, self.__class__)
    #new_method = profile(func.__get__(self, self.__class__))

    if old_method is not None:
        old_im_func = get_method_func(old_method)
        new_im_func = get_method_func(new_method)
        if not allow_main and old_im_func is not None and (
                get_funcglobals(old_im_func)['__name__'] != '__main__' and
                get_funcglobals(new_im_func)['__name__'] == '__main__'):
            if True or VERBOSE_CLASS:
                print('[util_class] skipping re-inject of %r from __main__' % method_name)
            return
        if old_method is new_method or old_im_func is new_im_func:
            #if verbose and util_arg.NOT_QUIET:
            #    print('WARNING: Skipping injecting the same function twice: %r' % new_method)
                #print('WARNING: Injecting the same function twice: %r' % new_method)
            return
        elif allow_override is False:
            raise AssertionError(
                'Overrides are not allowed. Already have method_name=%r' %
                (method_name))
        elif allow_override == 'warn':
            print(
                'WARNING: Overrides are not allowed. Already have method_name=%r. Skipping' %
                (method_name))
            return
        elif allow_override == 'override+warn':
            #import utool as ut
            #ut.embed()
            print('WARNING: Overrides are allowed, but dangerous. method_name=%r.' %
                  (method_name))
            print('old_method = %r, im_func=%s' % (old_method, str(old_im_func)))
            print('new_method = %r, im_func=%s' % (new_method, str(new_im_func)))
            print(get_funcglobals(old_im_func)['__name__'])
            print(get_funcglobals(new_im_func)['__name__'])
        # TODO: does this actually decrement the refcount enough?
        del old_method
    setattr(self, method_name, new_method)