On Sun, 09 Oct 2005 12:10:46 GMT, Ron Adam <[EMAIL PROTECTED]> wrote:
>Ron Adam wrote: >> >> Can anyone show me an example of of using dis() with a traceback? >> >> Examples of using disassemble_string() and distb() separately if >> possible would be nice also. > > [cliped] > >> But I still need to rewrite disassemble_string() and need to test it >> with tracebacks. >> >> Cheers, >> Ron > >It seems I've found a bug in dis.py, or maybe a expected non feature. >When running dis from a program it fails to find the last traceback >because sys.last_traceback doesn't get set. (a bug in sys?) It works >ok from the shell, but not from the program. > >Changing it to to get sys.exc_info()[2], fix's it in a program, but then >it doesn't work in the shell. So I replaced it with the following which >works in both. > > try: > if hasattr(sys,'last_traceback'): > tb = sys.last_traceback > else: > tb = sys.exc_info()[2] > except AttributeError: > raise RuntimeError, "no last traceback to disassemble" > >I'm still looking for info on how to use disassemble_string(). > One way to get dis output without modufying dis is to capture stdout: (ancient thing I cobbled together, no guarantees ;-) >>> class SOCapture: ... """class to capture stdout between calls to start & end methods, q.v.""" ... import sys ... def __init__(self): ... self.so = self.sys.stdout ... self.text = [] ... def start(self, starttext=None): ... """Overrides sys.stdout to capture writes. ... Optional starttext is immediately appended as if written to stdout.""" ... self.sys.stdout = self ... if starttext is None: return ... self.text.append(starttext) ... def end(self, endtext=None): ... """Restores stdout to value seen at contruction time. ... Optional endtext is appended as if written to stdout before that.""" ... self.sys.stdout = self.so ... if endtext is None: return ... self.text.append(endtext) ... def gettext(self): ... """Returns captured text as single string.""" ... return ''.join(self.text) ... def clear(self): ... """Clears captured text list.""" ... self.text = [] ... def write(self, s): ... """Appends written string to captured text list. ... This method is what allows an instance to stand in for stdout.""" ... self.text.append(s) ... >>> def foo(x): return (x+1)**2 ... >>> so = SOCapture() >>> import dis >>> so.start() >>> dis.dis(foo) >>> so.end() >>> print so.gettext() 1 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) 6 BINARY_ADD 7 LOAD_CONST 2 (2) 10 BINARY_POWER 11 RETURN_VALUE Or safer: >>> def diss(code): ... try: ... so = SOCapture() ... so.start() ... dis.dis(code) ... finally: ... so.end() ... return so.gettext() ... >>> diss(foo) ' 1 0 LOAD_FAST 0 (x)\n 3 LOAD_CONST 1 (1)\ n 6 BINARY_ADD \n 7 LOAD_CONST 2 (2)\n 10 BINARY_POWER \n 11 RETURN_VALUE \n' >>> print diss(foo) 1 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (1) 6 BINARY_ADD 7 LOAD_CONST 2 (2) 10 BINARY_POWER 11 RETURN_VALUE Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list