예제 #1
0
def get_attr_usage( func, attrpath ):
    ''' attrpath = [a, b, c] -> a.b.c
        attrpath = [1, b.c] -> func_args[1].b.c
    '''
    if not isinstance( func, Code):
        code = Code.from_code( getattr( func, 'im_func', func).func_code)
    else: code = func
    #print code.code
    root_var = attrpath[0]
    subattrs = attrpath[1:]
    if isinstance( root_var, int):  #argix
        root_var = code.args[ root_var]
    return get_var_attr_usage( code, root_var, subattrs)
예제 #2
0
def execode( func, noargs =True, get_all_data =False):
    '''expose func code as plain executable block without own namespace
    usage: pass all args/vars in locals/globals:
        cf = execode( func1)
        #no return value:
        exec cf in mylocalz( x=7, y=6, max= mymax )
        #with return value:
        r = eval( cf, mylocalz( x=9, y=0, max= mymax ) )

    ref: http://wiki.python.org/moin/ByteplayDoc
        http://www.voidspace.org.uk/python/articles/code_blocks.shtml
        http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/498242
    '''

    fc = getattr( func, 'im_func', func).func_code
    code = Code.from_code( fc)
    #XXX TODO:
    #   LOAD_DEREF -> LOAD_NAME: needs same to be done in all nested funcs!!
    #if opmap['LOAD_DEREF'] in [ c for c,a in code.code ]:
    #    print code.code
    #print code.code
    #print code.__dict__
    assert not code.varargs, func
    assert not code.varkwargs, func
    code.code = [ (replacer.get( opcode,opcode),arg) for opcode,arg in code.code]
    global_names = [ arg for opcode,arg in code.code if opcode == opload_glob ]
    code.newlocals = False  #no local namespace
    assert not code.freevars
    code.freevars = ()      #kill (to-be-bound) vars
    org_args = code.args
    if noargs:
        code.args = ()      #kill (to-be-bound) args
    c = code.to_code()
    #assert not fc.co_cellvars, fc.co_cellvars
    if not get_all_data: return c
    return c, org_args, global_names
    return dict( code=c, org_args=org_args, global_names=global_names)