0

For a wrapper function, why wouldn't the following approach work:

# 3. DISALLOW EXECUTION IN MAIN
def disallow_main(func):
    if __name__ == '__main__':
        raise RuntimeError("Cannot run from main.")
    return func

@disallow_main
def echo(prompt='-> '):
    _inp = input(prompt)
    print ("ECHO: %s" % _inp)

That is, why does it raise before defining the function? How should the wrap be constructed properly?

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
user12282936
  • 167
  • 2
  • 7
  • Because `if __name__ == '__main__'` is true and the decorated function is being executed before `echo`? – OneCricketeer Oct 28 '19 at 00:32
  • 1
    See also: https://stackoverflow.com/questions/341379/python-decorators-run-before-function-it-is-decorating-is-called – Mark Oct 28 '19 at 00:32
  • Please unaccept my answer. As noted in the comments, it only solves half of the issue. It explains why the check is happening at a time other than when you're expecting, but it still isn't checking the correct thing. – Carcigenicate Oct 28 '19 at 00:49

1 Answers1

0

As noted in the comments, this explains why the check is happening at the time it is, but still doesn't do what you want. This check only checks if the module containing disallow_main is __main__ or not; not if the calling code is __main__. You'll need a more complicated check to do exactly what you're after.


You need to wrap the passed function in a wrapper function that does the check. You're doing the check when the decorator is run, which is separate from when the function is called.

def disallow_main(func):
    def wrapper(*args):
        if __name__ == '__main__':
            raise RuntimeError("Cannot run from main.")
        else:
            func(*args)

    return wrapper

Note how wrapper is returned, and it calls func once it's done verification.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • 1
    This still doesn't actually work - it's checking the name of the module containing this code, *not* the code that's calling it. I think what you need to check is `inspect.currentframe(1).f_globals['__name__']` (that `1` may need to be higher to get the right stack frame). – jasonharper Oct 28 '19 at 00:44
  • That's true; that was sloppy. I'll add a note and I've requested they unaccept so I can delete it if needed. – Carcigenicate Oct 28 '19 at 00:52