Function that knows the names of its actual parameters

Quinn Dunkan quinn at pyro.ugcs.caltech.edu
Mon Jun 19 00:36:27 EDT 2000


On Sun, 18 Jun 2000 21:22:36 GMT, Stefan Franke <spamfranke at bigfoot.de> wrote:
>Huh? Are we talking about the same thing? Keyword arguments either overwrite
>existing ones or supply new ones along with the call. What I am looking for is
>more or less (and arguably sensible) syntactic sugar for building a subdict
>of locals() given non-quoted variable names:
>
>magic(a, b, ...) <-> {"a": locals("a"), "b": locals("b"), ...}
>
>This is obviously not meaningful for expressions as arguments. I don't making
>this look like a function call is a good thing, but I do think the functionality is
>quite useful sometimes (Python, HTML, SQL, etc. generation...).

Well, you asked for it.

This is a slightly modified function I posted a while back.  It gets confused
by functions across multiple lines, and by expressions which involve
variables.  And a bunch of other things, I'm sure.

import sys

def arghack(*_):
    try:
        1/0
    except:
        frame = sys.exc_info()[2].tb_frame.f_back
    func_name = frame.f_code.co_name
    co = frame.f_back.f_code
    c = map(ord, co.co_code)
    c.reverse()
    def getop(st=c):
        try:
            op = st.pop()
        except IndexError:
            return None, None
        oparg = None
        if op >= 90:
            oparg = st.pop() + st.pop() * 256
        return op, oparg

    while 1:
        op, oparg = getop()
        if op is None: break
        if op == 127 and oparg == frame.f_back.f_lineno:
            break

    while 1:
        op, oparg = getop()
        if op is None:
            raise "I'm lost"
        if (op == 101 or op == 116) and (
                co.co_names[oparg] == frame.f_code.co_name):
            break
    d = {}
    argno = 0
    op, oparg = getop()
    while 1:
        if op == 101:
            d[co.co_names[oparg]] = _[argno]
        elif op == 124:
            d[co.co_varnames[oparg]] = _[argno]
        elif op == 131:
            break
        else:
            d[argno] = _[argno]
            while op != 131 and op != 101 and op != 124:
                op, oparg = getop()
            continue
        argno = argno + 1
        op, oparg = getop()
    return d

foo, bar = 1, 2
def magic(a, b):
    print arghack(a, b)

magic(foo, bar)



More information about the Python-list mailing list