pythondebuggingline-numbersinspect

Debugging: Get filename and line number from which a function is called?


I'm currently building quite a complex system in Python, and when I'm debugging I often put simple print statements in several scripts. To keep an overview I often also want to print out the file name and line number where the print statement is located. I can of course do that manually, or with something like this:

from inspect import currentframe, getframeinfo

print getframeinfo(currentframe()).filename + ':' + str(getframeinfo(currentframe()).lineno) + ' - ', 'what I actually want to print out here'

Which prints something like:

filenameX.py:273 - what I actually want to print out here

To make it more simple, I want to be able to do something like:

print debuginfo(), 'what I actually want to print out here'

So I put it into a function somewhere and tried doing:

from debugutil import debuginfo
print debuginfo(), 'what I actually want to print out here'
print debuginfo(), 'and something else here'

Unfortunately, I get:

debugutil.py:3 - what I actually want to print out here
debugutil.py:3 - and something else here

It prints out the file name and line number on which I defined the function, instead of the line on which I call debuginfo(). This is obvious, because the code is located in the debugutil.py file.

So my question is actually: How can I get the filename and line number from which this debuginfo() function is called?


Solution

  • The function inspect.stack() returns a list of frame records, starting with the caller and moving out, which you can use to get the information you want:

    from inspect import getframeinfo, stack
    
    def debuginfo(message):
        caller = getframeinfo(stack()[1][0])
        print("%s:%d - %s" % (caller.filename, caller.lineno, message)) # python3 syntax print
    
    def grr(arg):
        debuginfo(arg)      # <-- stack()[1][0] for this line
    
    grr("aargh")            # <-- stack()[2][0] for this line
    

    Output:

    example.py:8 - aargh