Kevin Dangoor wrote:
>>> In order to introspect the function, we need direct access to it. I
>>> think the TurboGears decorators should all set an attribute on the
>>> function that has the original function object. That way, the
>>> decorators are a bit more flexible in terms of how they are arranged
>>> over the method in question.
>>>
>>> Opinions?
>> Ideally *all* decorators would be true invariants. Unfortunately doing
>> so would mean quite a serious rewrite (all except error_handler of
>> course ;))). However I belive this is still the best solution in the
>> long-run.
>
> Hmm... You're right. It would be nice for the decorators to be
> invariants or as close as possible to invariants. What would be nice
> is if the decorators actually maintained the signature of the
> functions they're decorating but added additional parameters as
> needed. I wonder how easy that would be?
Besides the invariant solution there are at least two other possibilities:
1) we introduce an attribute __undecorated__ serving as a reference to
the original function object.
2) as long as decorators preserve func_name (or __name__), the original
function can be had through func_closure. Proof of concept:
from itertools import ifilter, imap
import new
def extract(cell):
def code_donor(arg):
def extractor():
return arg
return extractor
code_donor = code_donor(None)
return new.function(code_donor.func_code, {}, None, None, (cell,))()
def get_original_func(func):
for func_obj in ifilter(lambda obj: isinstance(obj, FunctionType),
imap(extract, func.func_closure)):
if func_obj.__name__ == func.__name__:
return func_obj
Unfortunately 1) is ugly and 2) is quite hackish.
Simon