decorators only when __debug__ == True
LX
lxkain at gmail.com
Wed Mar 31 20:01:05 EDT 2010
On Mar 31, 2:28 pm, Stephen Hansen <apt.shan... at gmail.invalid> wrote:
> On 2010-03-31 13:59:01 -0700, LX said:
>
>
>
>
>
> >> pass_decorator will be called when the decorated function is _defined_,
> >> but not when the decorated function is _called_.
>
> > Why is it then that during runtime, with a breakpoint in some
> > arbitrary main() in main.py, I get something similar to the following
> > call stack:
>
> > main.py, line xxx, in <module>
> > main()
>
> > <string>, line 2, in main
>
> >decorator.py, line 261, in pass_decorator
> > return f(*args, **kw)
>
> > main.py, line yyy, in main()
> > * breakpoint line here *
>
> > It looks to me the call stack still includes the additional level of
> > thedecorator... what am I missing? Thank you for your time.
>
> You're not defining pass_decorator correctly. Always show us the actual
> code when you're showing results.
>
> Your pass_decorator should just return the original function,
> undecorated, unmodified if you're not in debug. It should only return a
> decorated function otherwise.
>
> Consider:
>
> -----
> fromdecoratorimportdecorator
>
> def debug_decorator(fn):
> if __debug__:
> def wrapper(fn, *args, **kwargs):
> # insert pre-condition testing here
> if len(args) != 1:
> raise ValueError("Incorrect number of arguments")
>
> result = fn(*args, **kwargs)
>
> # insert post-condition testing here
> if result not in (True, False):
> raise ValueError("Incorrect return value!")
>
> return result
> returndecorator(wrapper, fn)
> else:
> return fn
>
> @debug_decorator
> def my_test(arg):
> if not arg:
> raise RuntimeError
> return True
>
> my_test(0)
> -----
>
> And the output depending on if you're in debug mode or not:
> Top:test ixokai$ python deco.py
> Traceback (most recent call last):
> File "deco.py", line 27, in <module>
> my_test(0)
> File "<string>", line 2, in my_test
> File "deco.py", line 10, in wrapper
> result = fn(*args, **kwargs)
> File "deco.py", line 24, in my_test
> raise RuntimeError
> RuntimeError
>
> Top:test ixokai$ python -O deco.py
> Traceback (most recent call last):
> File "deco.py", line 27, in <module>
> my_test(0)
> File "deco.py", line 24, in my_test
> raise RuntimeError
> RuntimeError
>
> --
> --S
>
> ... p.s: change the ".invalid" to ".com" in email address to reply privately.
Thank you all a lot! The last 3 posts helped me figure it out. Indeed,
my pass_decorator function used "@decorator", using the decoratory.py
library. This prevented return of the original function. The code that
I have now is:
#NOT THIS:
#@decorator
#def pass_decorator(f, *args, **kw): # what about the slow-down that
incurs when using pass_decorator
#return f(*args, **kw)
def pass_decorator(f):
return f
@decorator
def trace_decorator(f, *args, **kw):
print "calling %s with args %s, %s" % (f.func_name, args, kw)
return f(*args, **kw)
trace_enable_flag = False #__debug__
trace = trace_decorator if trace_enable_flag else pass_decorator
More information about the Python-list
mailing list