ajabal
ajabal

Reputation: 31

using eval() function, how to evaluate an expression for a code under observation in python

I am creating a simple debugger using python and trying to create breakpoint when an expression holds.i am using the eval function to evaluate that expression.but it does not work.

def traceit(frame, event, trace_arg):
    if event == 'line':
        if(eval('x == 5')):
             print 'stop here'


def fn():
    #the variable x is defined and used here

sys.settrace(traceit)
fn()
sys.settrace(None)

Upvotes: 3

Views: 672

Answers (1)

mgilson
mgilson

Reputation: 309831

You need to pass a dictionary as an argument for locals and globals to the eval function (so that it knows what x is! -- Otherwise it's just guessing and it picks up the local context which isn't the context of the function fn)

You can get the locals and globals values from the stack frame object in the f_locals and f_globals attributes respectively.

I think you probably want something like:

eval('x == 5',frame.f_locals,frame.f_globals)

As a side note, you probably don't actually need eval for this (static) case:

if frame.f_locals.get('x') == 5:
   print "stop here"

Here's some "working" code (i.e. it prints "stop here" in the right spot):

import sys

def traceit(frame, event, trace_arg):
    if event == 'line':
        if 'x' in frame.f_locals or 'x' in frame.f_globals:
            if(eval('x == 5',frame.f_locals,frame.f_globals)):
                print 'stop here'
    return traceit

sentinel = object()
def trace_no_eval(frame, event, trace_arg):
    if event == 'line':
        value = frame.f_locals.get('x',frame.f_globals.get('x',sentinel))
        if value is not sentinel and value == 5:
            print 'stop here'
    return traceit


def fn():
    for x in range(10):
        print x

sys.settrace(traceit)
fn()
sys.settrace(trace_no_eval)
fn()
sys.settrace(None)

As you said that this is an assignment, please do not blindly copy this. Take the time to understand it and really understand what is going on.

Upvotes: 3

Related Questions