def automethodinfo(self=None,level=0):
    """
    Return a tuple (cls,self,method), where
    - cls is the class in wich you can find the definition of the method from which this function is called;
    - self is the instance passed as first argument to the method from which this function is called;
    - method is the unbound method from wich this function is called.
    If self is not None, the passed argument is used instead of the instance passed as first argument to the method in which this function is called.
    Pass to level an integer > 0 if you call this from a function nested in the method definition body.
    """
    from inspect import stack

    frame = stack()[level+1][0]
    code = frame.f_code
    name = code.co_name
    self = self or frame.f_locals[code.co_varnames[0]]

    cls = None

    f = None
    for c in type(self).__mro__:
        func_obj = f
        try:
            f = getattr(c,name)
            func_code = f.func_code
        except AttributeError:
            func_code = None

        if func_code is code:
            cls = c
        elif cls is not None:
            break

    if cls is None:
        raise TypeError, "Can only call 'automethodinfo' in a bound method"

    return cls,self,func_obj

    Return a tuple (cls,self,method), where
    - cls is the class in wich you can find the definition of the method from which this function is called;
    - self is the instance passed as first argument to the method from which this function is called;
    - method is the unbound method from wich this function is called.
    If self is not None, the passed argument is used instead of the instance passed as first argument to the method in which this function is called.
    Pass to level an integer > 0 if you call this from a function nested in the method definition body.
    
recipes/Python/412856_autosuper_to_the_limit/recipe-412856.py