Saturday, November 30, 2013

Using inspect.getargvalues to debug Python programs

By Vasudev Ram


I was looking through the Python docs recently, for ideas for any other useful debugging techniques, some time after I wrote this post about a simple Python debugging function.

Though I initially tried something else, I later came up with this technique, which may be helpful to debug Python programs. It uses the getargvalues function of Python's inspect module.

Here is a test program showing the use of inspect.getargvalues(); note that you have to pass the return value of inspect.currentframe() to inspect.getargvalues():
# test_getargvalues.py
# Author: Vasudev Ram - http://dancingbison.com

from debug1 import debug1
import inspect

def foo(arg1, arg2=None):
    print "In foo()"
    a = 1
    b = "2"
    c = True
    d = [ 3, "4" ]
    e = { 5: "five", "six": 6 }
    argvalues = inspect.getargvalues(inspect.currentframe())
    debug1("argvalues.args", argvalues.args)
    debug1("argvalues.varargs", argvalues.varargs)
    debug1("argvalues.keywords", argvalues.keywords)
    debug1("argvalues.locals", argvalues.locals)
    debug1("locals()", locals())

def bar(arg1, arg2, *args, **kwds):
    print "In bar()"
    argvalues = inspect.getargvalues(inspect.currentframe())
    debug1("argvalues.args", argvalues.args)
    debug1("argvalues.varargs", argvalues.varargs)
    debug1("argvalues.keywords", argvalues.keywords)
    debug1("argvalues.locals", argvalues.locals)
    debug1("locals()", locals())

def main():
    foo(1, 2)
    bar(1, 2, 3, 4, five=5, six=6)

main()
Run the program with:

python test_getargvalues.py

Here is its output:
In foo()
argvalues.args : ['arg1', 'arg2']
argvalues.varargs : None
argvalues.keywords : None
argvalues.locals : {'a': 1, 'c': True, 'b': '2', 'e': {'six': 6, 5: 'five'}, 'd': [3, '4'], 'arg1': 1, 'arg2': 2}
locals() : {'a': 1, 'c': True, 'b': '2', 'e': {'six': 6, 5: 'five'}, 'd': [3, '4'], 'arg1': 1, 'arg2': 2, 'argvalues': ArgInfo(args=['arg1', 'arg2'], varargs=None, keywords=None, locals={...})}
In bar()
argvalues.args : ['arg1', 'arg2']
argvalues.varargs : 'args'
argvalues.keywords : 'kwds'
argvalues.locals : {'arg1': 1, 'arg2': 2, 'args': (3, 4), 'kwds': {'six': 6, 'five': 5}}
locals() : {'arg1': 1, 'arg2': 2, 'args': (3, 4), 'kwds': {'six': 6, 'five': 5}, 'argvalues': ArgInfo(args=['arg1', 'arg2'], varargs='args', keywords='kwds', locals={...})}
Note that for comparison, I also printed the value of the Python built-in locals(), and found that the output of locals() is almost the same as, but a subset, of the output of getargvalues() - at least when the function which you are debugging has varargs and keyword arguments.

Read other posts about Python on jugad2.
- Vasudev Ram - Dancing Bison Enterprises
Contact Page


O'Reilly 50% Ebook Deal of the Day


No comments: