Given x = C.f after:
class C:
    def f(self):
        pass
What do I call on x that will return C?
The best I could do is execing a parsed portion of x.__qualname__, which is ugly:
exec('d = ' + ".".join(x.__qualname__.split('.')[:-1]))
For a use case, imagine that I want a decorator that adds a super call to any method it's applied to. How can that decorator, which is only given the function object, get the class to super (the ??? below)?
def ensure_finished(iterator):
    try:
        next(iterator)
    except StopIteration:
        return
    else:
        raise RuntimeError
def derived_generator(method):
    def new_method(self, *args, **kwargs):
        x = method(self, *args, **kwargs)
        y = getattr(super(???, self), method.__name__)\
            (*args, **kwargs)
        for a, b in zip(x, y):
            assert a is None and b is None
            yield
        ensure_finished(x)
        ensure_finished(y)
    return new_method
 
     
     
     
     
    