[portland] Follow up to last night

Matt McCredie mccredie at gmail.com
Thu Apr 10 01:46:51 CEST 2008

Hi all,

     Last night Jason gave a demo "Using inspect + exec to match
function signatures". He mentioned that  the decorated function still
didn't have the correct filename. I brought something up, I don't
think anybody really followed what I was saying. Anyway, here is what
I was getting at, and it seems to work.

    Seems to work. Feedback welcome.


import codeop
import inspect
import warnings

def deprecated(fn):
    """Decorate a function and issue a deprecation warning on execution."""
    spec = inspect.getargspec(fn)
    func_name = fn.func_name
    argspec = inspect.formatargspec(*spec)
    callspec = inspect.formatargspec(*spec[:3])

    # adding newlines seems to be the easiest way to get the line number to
    # report correctly.

    text = "\n"*fn.func_code.co_firstlineno + """\
def %(func_name)s%(argspec)s:
    return fn%(callspec)s
    text %= locals()

    # compile it with the appropriate file name
    code = codeop.compile_command(text, fn.func_code.co_filename, "exec")

    env = locals().copy()
    env['warnings'] = warnings

    # just exec the code object instead of the string
    exec code in env
    env[func_name].func_doc = fn.func_doc
    return env[func_name]

More information about the Portland mailing list