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

Reply via email to