dis.dis question
Bengt Richter
bokr at oz.net
Sat Oct 15 21:47:19 EDT 2005
On Sun, 09 Oct 2005 12:10:46 GMT, Ron Adam <rrr at ronadam.com> 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
More information about the Python-list
mailing list