wrapping all class methods

Robin Becker robin at jessikat.fsnet.co.uk
Sun Nov 17 05:56:39 EST 2002


In article <ar6jkk$17g$0 at 216.39.172.122>, Bengt Richter <bokr at oz.net>
writes
......
>>..... no I hadn't used that, but then I don't want a trace I want to
>>discover which tracebacks are being detected and trapped.
>
>I thought you might be able to do a silent trace and see the exceptions
>before they're "trapped". (The hook doesn't do any output or force you to.
>You choose what to do if/when you see something of interest).
>

this is probably a good way to go as it is non-invasive, but it's a new
technology for me so I'd need to wrap my decreasing neurones around it
before use.

The wrapping approach applies itself to all classes and all method
members, but in my example I see base class methods are also being
wrapped which may or may not be desired.

I suppose a global tracefunc could check at each 'call' whether the
currently entered scope is wanted and then set a local trace.

I wonder how fast this is compared to the wrapping approach.

>E.g., this is what my tracewatch does being told to watch only calls
>and returns from foo and bar, but incidentally reporting on exceptions:
>
> >>> from ut.tracewatch import TraceWatch as TW
> >>> def foo(n):
> ...     if n>4: raise StopIteration # or whatever
> ...     bar(n+1)
> ...
> >>> def bar(n):
> ...     if n>3: foo(n+1)
> ...     try:
> ...         foo(n+1)
> ...     except StopIteration:
> ...         print 'Caught stopiter with n = %s' % n
> ...
> >>> tw=TW()
> >>> tw.addwatch('foo','#f')
> >>> tw.addwatch('bar','#f')
> >>> tw.on()
> >>> foo(2)
> --------------------------------------------------------------------
> File: "<stdin>"
> Line [scope] C:all, R:eturn eX:cept S:tack N:ew M:od E:quiv U:nbound
> ---- ------- -------------------------------------------------------
>    1 [foo]:             C: foo(n=2)
>    1 [bar]:             C: bar(n=3)
>    1 [foo]:             C: foo(n=4)
>    1 [bar]:             C: bar(n=5)
>    1 [foo]:             C: foo(n=6)
>    2 [foo]:             X: StopIteration()
>                         S: < bar:2 < foo:3 < bar:4 < foo:3 < ?:1
>    2 [bar]:             X: StopIteration()
>                         S: < foo:3 < bar:4 < foo:3 < ?:1
>    3 [foo]:             X: StopIteration()
>                         S: < bar:4 < foo:3 < ?:1
>    4 [bar]:             X: StopIteration()
>                         S: < foo:3 < ?:1
> Caught stopiter with n = 3
>    6 [bar]:             R: bar(...) => None
>    3 [foo]:             R: foo(...) => None
>
>Whereas if we start off with foo at 3, bar won't set the trap, so we get
>the full unwind and no returns (R:):
>
> >>> foo(3)
>    1 [foo]:             C: foo(n=3)
>    1 [bar]:             C: bar(n=4)
>    1 [foo]:             C: foo(n=5)
>    2 [foo]:             X: StopIteration()
>                         S: < bar:2 < foo:3 < ?:1
>    2 [bar]:             X: StopIteration()
>                         S: < foo:3 < ?:1
>    3 [foo]:             X: StopIteration()
>                         S: < ?:1
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 3, in foo
>   File "<stdin>", line 2, in bar
>   File "<stdin>", line 2, in foo
> StopIteration
>
>Regards,
>Bengt Richter

-- 
Robin Becker



More information about the Python-list mailing list