Improving stack trace hook in python

All,

I have a question similar to question 2617120 found here:

how to use traceit to input variable input

where the questioner needs pointers on how to make the parameters of the python print function when they were done using trace trace.

I am looking for something very similar to this, but with a twist. Instead of unloading all the data, I want to evaluate the code when I run it and print any changed variables. For example, with the following code:

for modname in modnames:                   

if not modname or '.' in modname:      
     continue                                                                    
...                                  

the trace hook will cause the following:

for modname in modnames:                | for init in init,., encoding
                                        |
if not modname or '.' in modname:       | if not init or '.' in init
     continue                           |     continue
if not modname or '.' in modname:       | if not . or '.' in .
...                                     |

where the line of code is interpolated based on the current frame. I did this in perl, where it is salvation under certain circumstances.

- python? , , ( )

btw - :

import sys
import linecache
import random

def traceit(frame, event, arg):
    if event == "line":
        lineno = frame.f_lineno
        filename = frame.f_globals["__file__"]
        if filename == "<stdin>":
            filename = "traceit.py"
        if (filename.endswith(".pyc") or
            filename.endswith(".pyo")):
            filename = filename[:-1]
        name = frame.f_globals["__name__"]
        line = linecache.getline(filename, lineno)
        print "%s:%s:%s: %s" % (name,  lineno,frame.f_code.co_name,line.rstrip())
    return traceit


def main():
    print "In main"
    for i in range(5):
        print i, random.randrange(0, 10)
    print "Done."

sys.settrace(traceit)
main()
+3
1

, - , line frame ( traceit ).

import re
from types import *

def interpolatevar(matchobj):
    excludetypes = set((NoneType, TypeType, FunctionType, LambdaType, ClassType,
                    CodeType, InstanceType, MethodType, BuiltinFunctionType,
                    BuiltinMethodType))

    var = matchobj.group(0)
    basevar = var.split(".")[0]
    if basevar in frame.f_code.co_names or basevar in frame.f_code.co_varnames:
        if basevar in frame.f_globals or basevar in frame.f_locals:
            val = eval(var, frame.f_globals, frame.f_locals)
            if type(val) not in excludetypes:
                return repr(val)
    return var

line = re.sub(r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*", 
              interpolatevar, line)

, , , .

(, foo.bar ), , , , foo <function foo at 0x02793470> doesn ' , . ( , , types.)

, , - , , . ast , , , , .

0

Source: https://habr.com/ru/post/1779102/