Search code examples
pythonintrospection

Is it possible for a callee to force its caller to return in python?


Is it possible for a callee to force its caller to return in python? If so, is this a good approach? Doesn't it violate the Explicit is better than implicit. sentence of the Zen of Python?

Example:

import inspect

class C(object):
    def callee(self):
        print 'in callee'
        caller_name = inspect.stack()[1][3]
        caller = getattr(self, caller_name)
        # force caller to return
        # so that "in caller after callee" gets never printed

        caller.return() # ???

    def caller(self):
        print 'in caller before calle'
        self.callee()
        print 'in caller after callee'

c = C()

c.caller()

print 'resume'

Output:

in caller before callee
in callee
resume

Finally, thanks to @Andrew Jaffe's suggestion on context managers I resolved it with a simple decorator.

# In my real code this is not a global variable
REPORT_ERRORS = True

def error_decorator(func):
    """
    Returns Event instance with result of the
    decorated function, or caught exception.
    Or reraises that exception.
    """

    def wrap():
        error = None
        user = None

        try:
            user = func()
        except Exception as e:
            error = e
        finally:
            if REPORT_ERRORS:
                return Event(user, error)
            else:
                raise error 
    return wrap


@error_decorator
def login():

    response = fetch_some_service()

    if response.errors:
        # flow ends here
        raise BadResponseError

    user = parse_response(response)

    return user

Solution

  • What's wrong in returning a value from the callee, to be read by caller and thus behave accordingly?

    instead of

    caller.return() # ???
    

    write

    return False
    

    and in

    def caller(self):
            print 'in caller before calle'
    
            rc = self.callee()
            if not rc:
                 return
            print 'in caller after callee'
    

    and off course you can raise exception and catch it in the callee and behave accordingly or simply less it fall through

    Duplicate of mgilson

    Reason I would argue for Return Value based check

    1. Explicit is better than implicit
    2. Callee should not control the Caller Behavior. Its a bad programming practice. Instead Callers should change its behavior based on callee's behavior.