Fabiano Sidler wrote: [snipped]
> The problem with this is that the func_code attribute would contain > the code of PrintingFunction instead of func. What I wanted to do, is > to keep the original behaviour, i.e. set the variable __metaclass__ to > DebugMeta and so get debug output, without changing a function and > getting the original function's code object by the func_code > attribute, not PrintigFunction's one. That's why I *must* inherit from > <type 'function'>. No, you don't have to: >>> import new >>> import types >>> class DebugFunction(object): ... def __init__(self, func): ... object.__setattr__(self, 'func', func) ... def __get__(self, obj, objtype): ... return new.instancemethod(self, obj, objtype) ... def __call__(self, *args, **namedargs): ... print args, namedargs ... func = object.__getattribute__(self, 'func') ... return func(*args, **namedargs) ... def __getattribute__(self, name): ... func = object.__getattribute__(self, 'func') ... return getattr(func, name) ... def __setattr__(self, name, value): ... func = object.__getattribute__(self, 'func') ... setattr(func, name, value) ... def __delattr__(self, name): ... func = object.__getattribute__(self, 'func') ... delattr(func, name) ... >>> class DebugMeta(type): ... def __new__(meta, name, bases, dict): ... for name, obj in dict.iteritems(): ... if isinstance(obj, types.FunctionType): ... dict[name] = DebugFunction(obj) ... return type.__new__(meta, name, bases, dict) ... >>> class Example(object): ... __metaclass__ = DebugMeta ... def spam(self, *args, **namedargs): ... """Spam spam spam spam. Lovely spam! Wonderful spam!""" ... pass ... >>> e = Example() >>> e.spam('eggs', anwser=42) (<__main__.spam object at ...>, 'eggs') {'anwser': 42} >>> e.spam.__doc__ 'Spam spam spam spam. Lovely spam! Wonderful spam!' >>> e.spam.im_func.func_code <code object spam at ..., file "<stdin>", line 3> > Greetings, > F. Sidler Ziga -- http://mail.python.org/mailman/listinfo/python-list