AssertionError not caught?
This one has me mystified good! This works (print statement is executed as the Exception is caught) as advertised: try: raise AssertionError except AssertionError: print "caught AssertionError" But this one does not: def test(): raise AssertionError try: test() except AssertionError: print "caught AssertionError" other errors (e.g. IOError) work fine! This is on OSX 10.5.6, with the standard Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) [GCC 4.0.1 (Apple Computer, Inc. build 5341)]. Is this a bug? Any hints / help would be much appreciated! Thank you. -- http://mail.python.org/mailman/listinfo/python-list
decorators only when __debug__ == True
Hi all, I have a question about decorators. I would like to use them for argument checking, and pre/post conditions. However, I don't want the additional overhead when I run in non-debug mode. I could do something like this, using a simple trace example. @decorator def pass_decorator(f, *args, **kw): # what about the slow-down that incurs when using pass_decorator? return f(*args, **kw) @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 Trouble is, there is still an additional encapsulating function call. Is there any way to eliminate the extra function call altogether? Thanks in advance! -- http://mail.python.org/mailman/listinfo/python-list
Re: decorators only when __debug__ == True
On Mar 29, 6:34 pm, MRAB wrote: > LX wrote: > > Hi all, I have a question about decorators. I would like to use them > > for argument checking, and pre/post conditions. However, I don't want > > the additional overhead when I run in non-debug mode. I could do > > something like this, using a simple trace example. > > > @decorator > > def pass_decorator(f, *args, **kw): # what about the slow-down that > > incurs when using pass_decorator? > > return f(*args, **kw) > > > @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 > > > Trouble is, there is still an additional encapsulating function call. > > Is there any way to eliminate the extra function call altogether? > > Thanks in advance! > > I think you have misunderstood certain details about decorators. > > This code with a decorator: > > �...@decorator > def hello(): > print "hello world" > > basically does this: > > def hello(): > print "hello world" > hello = decorator(hello) > > so your non-decorator just needs to return the function it was passed: > > def pass_decorator(func): > return func > > and your trace decorator would be something like this: > > def trace_decorator(func): > def show(*args, **kwargs): > print "calling %s with args %s, %s" % (func.func_name, > args, kwargs) > result = func(*args, **kwargs) > print "returning %s from %s" % (result, func.func_name) > return result > return show Sure, but during runtime, pass_decorator will still be called, even though it doesn't do anything. I am wondering if I can disable this additional function call at non-debug runtime. In other words, I want the calling stack to contain no decorator at all, not even pass_decorator. I should mention that, in my code, the symbol "decorator" is imported from Michele Simionato's decorator.py file. -- http://mail.python.org/mailman/listinfo/python-list
Re: decorators only when __debug__ == True
On Mar 29, 7:11 pm, Steven D'Aprano wrote: > On Mon, 29 Mar 2010 17:54:26 -0700, LX wrote: > > Hi all, I have a question about decorators. I would like to use them for > > argument checking, and pre/post conditions. However, I don't want the > > additional overhead when I run in non-debug mode. I could do something > > like this, using a simple trace example. > > def decorator(func): > if __debug__: > @functools.wraps(func) > def inner(*args, **kwargs): > preprocess() > result = func(*args, **kwargs) > postprocess() > return result > return inner > else: > return func > > -- > Steven Actually, I am using "decorator" from Michele Simionato's decorator.py file, at http://pypi.python.org/pypi/decorator. -- http://mail.python.org/mailman/listinfo/python-list
Re: decorators only when __debug__ == True
On Mar 30, 2:41 pm, MRAB wrote: > LX wrote: > > On Mar 29, 6:34 pm, MRAB wrote: > >> LX wrote: > >>> Hi all, I have a question about decorators. I would like to use them > >>> for argument checking, and pre/post conditions. However, I don't want > >>> the additional overhead when I run in non-debug mode. I could do > >>> something like this, using a simple trace example. > >>> @decorator > >>> def pass_decorator(f, *args, **kw): # what about the slow-down that > >>> incurs when using pass_decorator? > >>> return f(*args, **kw) > >>> @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 > >>> Trouble is, there is still an additional encapsulating function call. > >>> Is there any way to eliminate the extra function call altogether? > >>> Thanks in advance! > >> I think you have misunderstood certain details about decorators. > > >> This code with adecorator: > > >> �...@decorator > >> def hello(): > >> print "hello world" > > >> basically does this: > > >> def hello(): > >> print "hello world" > >> hello =decorator(hello) > > >> so your non-decoratorjust needs to return the function it was passed: > > >> def pass_decorator(func): > >> return func > > >> and your tracedecoratorwould be something like this: > > >> def trace_decorator(func): > >> def show(*args, **kwargs): > >> print "calling %s with args %s, %s" % (func.func_name, > >> args, kwargs) > >> result = func(*args, **kwargs) > >> print "returning %s from %s" % (result, func.func_name) > >> return result > >> return show > > > Sure, but during runtime, pass_decorator will still be called, even > > though it doesn't do anything. I am wondering if I can disable this > > additional function call at non-debug runtime. In other words, I want > > the calling stack to contain nodecoratorat all, not even > > pass_decorator. > > > I should mention that, in my code, the symbol "decorator" is imported > > from Michele Simionato'sdecorator.py file. > > 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 main() , 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 the decorator... what am I missing? Thank you for your time. -- http://mail.python.org/mailman/listinfo/python-list
Re: decorators only when __debug__ == True
On Mar 31, 2:28 pm, Stephen Hansen 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
> > main()
>
> > , 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
> my_test(0)
> File "", 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
> 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
--
http://mail.python.org/mailman/listinfo/python-list
