using trace to do 'in place' evaluation of variables
All, I've been using the trace module for python (as per http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html), and would very much like to have a feature there that I've implemented for perl already. Namely, I would like output in the format as described on that page, but with the ability to have the running window partitioned into 2, like: /tmp/file.py:13: yy = 12 | = 12 /tmp/file.py14: xx = yy | = 12 where the window on the left shows the actual source code, and the right shows how that code eval's (ie: how the scalars resolve based on their current scope.) Is this possible given the current trace functionality? I've found it an *incredible* time saver with my perl code, especially for hard to find data bugs - to debug I simply look for a pattern which is associated with a given bug, and then backtrack that pattern to where it first appeared in my code. Also, is there a good archive searcher for the python-list archives? Short of doing a complete download of http://mail.python.org/pipermail/python-list/ and indexing it, I don't see how I can do a decent pattern search on previous archive entries.. Thanks much, Ed -- http://mail.python.org/mailman/listinfo/python-list
completely implicit interpolation based on a frame object
All, Ok, it looks like in order to implement a tracer that does interpolation, I'm going to have to hack around with frames. Perl's interpolation is fairly straightforward, to do interpolation of $a == 1 all you need to do is put quotes around "$a == 1" to have $a evaluated. So, I'd like to do the same thing with python. It looks like I can do the same thing with frames, ie: interpolate_frame(frame, "if not wx.Platform == '__WXMAC' ") would interpolate wx based off of the frame that you passed to interpolate_frame, because wx is in the f_locals or f_globals dictionary. Hence, this would become: loc_wx = _first_defined(frame.f_locals["wx"], frame.f_globals["wx"]) return "if not ", loc_wx.Platform , " == \"__WXMAC\"" which would then do the interpolation. I guess my question is - has something like this been released? I see some close hits, namely Evan Forsmark's http://www.evanfosmark.com/2008/06/string-interpolation-in-python/ but I don't see anything exact, and getting this right would be fairly tricky, so I was hoping for canned solution. Any ideas would be great on this, including pitfalls that people see in implementing it. Ed -- http://mail.python.org/mailman/listinfo/python-list
Re: completely implicit interpolation based on a frame object
>> Any ideas would be great on this, including pitfalls that people see >> in implementing it. >> > http://docs.python.org/library/string.html#template-strings > > regards > Steve Steve, Thanks for the tip, I did look at templates and decided that they weren't quite completely what I was looking for, although they could be part of the solution. 1. they require ${ } around the variables in question that you want to interpolate. When run through the trace hook, normal code doesn't do that. 2. they don't provide (AFAICT) a complete interpolation solution. Suppose I want to define custom interpolations in my tracer, like say, expanding out lists and dicts, or fleshing out objects using their stringification method. Does template do this? Formats may be a bit closer here, but I'm not sure if they are workable (or usable) with 2.5... which is where I need to work. Ed -- http://mail.python.org/mailman/listinfo/python-list
Re: completely implicit interpolation based on a frame object (nn)
>> a bit closer here, but I'm not sure if they are >> workable (or usable) with 2.5... which is where I need to work. >> >> Ed > > One of the solutions from here might work for you: > > http://wiki.python.org/moin/Templating > Ok, cool. A couple of followups - I'd be interested in knowing which of the solutions listed there was: 1. lightweight 2. usable with 2.5 (and if possible 2.3,2.2, and 2.1) 3. able to do inplace expansion of arrays and/or hashes, using arbitrary functions, in a simplistic way (perhaps like formats and the {var!func} syntax) I'll read up on them, but as it is with perl, you can spend a lot of time fiddling around with a module to find out that the implementation doesn't support the featureset that you are looking for, or otherwise is just plain junk, so pointers are definitely welcome on which one to use. -- Anyways, the problem isn't completely solved here. Since it is a free-flowing string that needs to be interpolated, there needs to be some way of picking out the identifiers that are to be evaluated and turning them into a template. In the following code: person="mary" print "then along came a person named ", person this has to evaluate to print "then along came a person named ", mary There's also subtleties here - if foo.somesuch is an attribute, there is no chance of a side effect, but if foo.somesuch is a property, then it could inadvertently cause side effects, and only one side effect can totally ruin your day (that was the bulk of the complexity in the perl version of this, ensuring no side effects in the expanded vars) Likewise, if a line of code spans multiple lines, you may have identifiers that span these multiple lines which means you may miss some substitutions. So, again, I'm interested in ways of getting around these problems. In perl its very easy to do this because of sigils, would very much like to know how to do the same thing in python. thanks much, Ed (ps - this is what I've got so far, which is basically cobbled together from stuff on stackoverflow. Works ok, but lines #15-#16 AFAICT are the one that needs to be bulletproofed: 1 import sys 2 import linecache 3 import random 4 5 def traceit(frame, event, arg): 6 if event == "line": 7 lineno = frame.f_lineno 8 filename = frame.f_globals["__file__"] 9 if filename == "": 10filename = "traceit.py" 11if (filename.endswith(".pyc") or 12filename.endswith(".pyo")): 13filename = filename[:-1] 14name = frame.f_globals["__name__"] 15line = linecache.getline(filename, lineno) 16print "%s:%s:%s: %s" % (name, lineno,frame.f_code.co_name,line.rstrip()) 17return traceit 18 20 sys.settrace(traceit) 21 main() ) ( pps - is there a collection of tracers somewhere? This seems definitely the thing that you'd want to collect in a library somewhere, and switch tracers as you see fit depending on what you are looking for.. ) -- http://mail.python.org/mailman/listinfo/python-list
trace options
All, I've been looking at the trace module, and although it looks useful, I'm surprised that there aren't a couple of features that I would have thought would be fairly basic. So, does trace support (for the --trace option): - indentation tracking stacklevel (where each function is prefixed by tabs equal to the number of stacklevels deep in the program) - output to something other than sys.stdout (eg. output to a file specified either by environmental variable or by parameter). - mult-threaded programs going to multiple output handles, especially in light of the above - fully qualified python modules in path: (eg: /path/to/module/my_module.py(1): print "HERE" instead of my_module.py(1): print "HERE". Ultimately, I'd like to be able to look at two runs of a program and be able to pinpoint the very first difference between thembased on the output of their trace runs. As it stands, I really can't do this. Of course I could implement the above, but I was hoping to avoid duplicated effort if someone has already implemented options like this..I posted the above to the python-dev list, they suggested I take it here, so any help would be appreciated. Ed -- http://mail.python.org/mailman/listinfo/python-list