From: Ype K. <yk...@xs...> - 2001-11-19 20:06:08
|
Finn, Some weeks ago I reported the bug below. I tried to isolate it but this proved to take too much of my time, given the workaround. Since the workaround is not really straightforward it might be worthwhile to somehow make it available until someone else runs into it the bug and is able to isolate it. The workaround is to use a method of an object as the trace function instead of a function defined in module scope. Is a bug report the right way to make the workaround available? Regards, Ype :( > >> >> > >> > >> >def tracer(frame, why, arg): >> > print why, frame.f_lineno, arg >> > return tracer >> > >> >def foo(): >> > for i in range(10): >> > a = "abc" >> > a = "Done" >> > >> >import sys >> >sys.settrace(tracer) >> >foo() >> >> I'll give it a try, >> > >This works fine when called interactively. >However when I use it via execfile() i get a: >NameError: tracer >on the "return tracer" statement. It is not only via execfile(), a lot more is going in between, ao. the dictionary against which the execfile() is executed is the __dict__ of a new.module(). This is used within several try/except and try/finally blocks on the stack frames of several method invocations. > >The following works when called via execfile(), >the interesting difference is probably the fact >that the tracer function is now not in a module >name space when returned for line tracing, >so I think there is a bug related to the new nested >namespaces in execfile(): I looked around in the jython source code for the nested scopes, but could not find anything that might relate to this. > > >class LineInfoCollector: > def __init__(self): > self.lineInfos = {} > > def addLineInfo(self, lineInfo): > self.lineInfos[lineInfo] = 1 > > def getLineInfos(self): > infos = self.lineInfos.keys() > infos.sort() > return infos > > def tracer(self, frame, why, arg): > self.addLineInfo((frame.f_code.co_filename, > frame.f_code.co_name, > frame.f_lineno, > why, arg)) > return self.tracer > >def foo(): > for i in range(2): > a = "abc" > a = "Done" > >if __name__ == '__main__': > import sys > > ltrac = LineInfoCollector() > sys.settrace(ltrac.tracer) > try: foo() > finally: sys.settrace(None) > > print 'Lines covered:' > for lineInfo in map(str, ltrac.getLineInfos()): > print lineInfo > |