Getting better traceback info on exec and execfile - introspection?

R. Bernstein rocky at panix.com
Mon Jan 16 05:00:00 CET 2006


"Ziga Seilnacht" <ziga.seilnacht at gmail.com> writes:
> You should check the getFrameInfo function in zope.interface package:
> http://svn.zope.org/Zope3/trunk/src/zope/interface/advice.py?rev=25177&view=markup

Thanks! Just looked at that. The logic in the relevant part (if I've extracted
this correctly):

    f_globals = frame.f_globals
    hasName = '__name__' in f_globals
    module = hasName and sys.modules.get(f_globals['__name__']) or None
    namespaceIsModule = module and module.__dict__ is f_globals
    if not namespaceIsModule:
        # some kind of funky exec
        kind = "exec"

is definitely not obvious to me. exec's don't have module namespace
(or something or other)?  Okay. And that the way to determine the
module-namespace thingy is whatever that logic is? Are the assumptions
here be likely to be valid in the future? 

Another problem I have with that code is that it uses the Zope Public
License. But the code is adapted from the Python Enterprise
Application Kit (PEAK) which doesn't seem to use the Zope Public
License. I'm not sure it's right to adopt a Zope Public License just
for this.

So instead, I followed the other avenue I suggested which is
dissembling the statement around the frame. Talk about the kettle
calling the pot black! Yes, I don't know if the assumptions in this
method are likely to be valid in the future either.

But I can use op-code examination to also help me determine if we are
stopped at a def statement which I want to skip over. So here's the
code I've currently settled on:

from opcode import opname
def op_at_frame(frame):
    code = frame.f_code.co_code
    pos  = frame.f_lasti
    op = ord(code[pos])
    return opname[op]

def is_exec_stmt(frame):
    """Return True if we are looking at an exec statement"""
    return frame.f_back is not None and op_at_frame(frame.f_back)=='EXEC_STMT'

re_def = re.compile(r'^\s*def\s+')
def is_def_stmt(line, frame):
    """Return True if we are looking at a def statement"""
    # Should really also check that the operand is a code object
    return re_def.match(line) and op_at_frame(frame)=='LOAD_CONST'

But it may just be because I wrote it that I find it easier to
understand and more straightforward to fathom.

> > And suppose instead of '<string>' I'd like to give the value or the
> > leading prefix of the value instead of the unhelpful word '<string>'?
> > How would one do that? Again, one way is to go into the outer frame
> > get the source line (if that exists), parse that and interpolate
> > argument to exec(file). Is there are better way?
> 
> Py library (http://codespeak.net/py/current/doc/index.html) has some
> similar functionality in the code subpackage.

Again, many thanks. I'll have to study this further. It may be that
exec and so on are wrapped so that it's possible to squirrel away the
string before calling exec. Again, dunno. But thanks for the pointer.



More information about the Python-list mailing list