Getting a python traceback without an exception
Asked Answered
F

1

16

Suppose you have these modules:

module1.py

import module2

def a():
    module1.b()

def c():
    print "Hi guys!"

module2.py

import module1

def b():
    module1.c()

I want a function func(a()) that produces a similar output to this: (=a traceback ?)

 /usr/local/lib/python2.7/dist-packages/test/module1.py
   3 def a():
   4     module1.b()

   1 import module1

 /usr/local/lib/python2.7/dist-packages/test/module2.py
   3 def b():
   4     module1.c()

   1 import module2

 /usr/local/lib/python2.7/dist-packages/test/module1.py
   6 def c():
   7     print "Hi guys!"

It might be possible with the standard modules traceback and/or cgitb and/or inspect but I am having a hard time figuring out these modules from the documentation.

I thought it was possible doing traceback.print_stack(a()) but it just kept on loading forever for some reason. I tried other functions in those modules but without success.

UPDATE 3

@jterrace

python trapy_module.py :

import trace

def trapy(arg):
    tracer = trace.Trace()
    tracer.run(arg)
    r = tracer.results()
    r.write_results()

if __name__ == '__main__':
    import random
    trapy('random.random()')

Now when I do: python trapy_module.py I get:

--- modulename: trapy, funcname: <module>
<string>(1): 

Replacing import random with import pyglet and random.random() with pyglet.app.run() just keeps running without outputting anything.

Frederigo answered 14/6, 2012 at 16:11 Comment(1)
ITYM module2.b() or alternatively from module2 import b.Sarena
A
23

traceback.print_stack works nicely for me:

>>> import traceback
>>> def what():
...    traceback.print_stack()
... 
>>> def hey():
...    what()
... 
>>> hey()
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in hey
  File "<stdin>", line 2, in what

UPDATE:

You've made it clear you really don't want a traceback. You want tracing information. Here's a way you can get some trace info:

#tracetest.py

def what():
    return 3

def hey():
    return what()

def yo():
    return hey()

import trace
tracer = trace.Trace()
tracer.run("yo()")
r = tracer.results()
r.write_results()

and running the above:

$ python tracetest.py
 --- modulename: tracetest, funcname: <module>
<string>(1):   --- modulename: tracetest, funcname: yo
tracetest.py(8):     return hey()
 --- modulename: tracetest, funcname: hey
tracetest.py(5):     return what()
 --- modulename: tracetest, funcname: what
tracetest.py(2):     return 3
Agriculture answered 14/6, 2012 at 17:56 Comment(11)
Thank you for this. But I'd like to e.g. trace back pyglet.app.run() without needing to touch the pyglet project code.Frederigo
I think you want the trace module. Updated the answer.Agriculture
Thank you again. This works in that example but not for some functions/object instantiations in other libraries apparently. Do you know why? See my update in the original post.Frederigo
Were you running from the command line? Trace only works from filesAgriculture
Ow, I was. I ran it as a file now but still not what it should be. (see update 2 of the original post)Frederigo
You are passing a function not a string. You need to pass "random.random()" not random.random()Agriculture
I did pass a string, look at the third line of the trapy function: tracer.run(str(arg)) .Frederigo
No you didn't. str(random.random()) is NOT "random.random()"Agriculture
Thank you for noticing this! I passed a string "random.random()" now (see edit 3), but the output is still the same though.Frederigo
That's because random.random is a native call. You won't get tracing information for that.Agriculture
There's a random.py file in usr/lib/python2.7, there are no math.py or the sys.py files in there. So I thought that was possible. But I guess it is because random.random() also makes use of other modules which are not written using only python(such as math). Thank you for your help.Frederigo

© 2022 - 2024 — McMap. All rights reserved.