[Python-Dev] Updated PEP 362 (Function Signature Object)

Steven D'Aprano steve at pearwood.info
Fri Jun 8 04:08:09 CEST 2012


Nick Coghlan wrote:
> On Fri, Jun 8, 2012 at 4:34 AM, Larry Hastings <larry at hastings.org> wrote:
>> In other words: this is possible but extremely unlikely, and will only be
>> done knowingly and with deliberate intent by a skilled practitioner.
>>>> I think it's reasonable to declare that, if you're monkeying around with
>> dunder attributes on a function, it's up to you to clear the f.__signature__
>> cache if it's set. Like Spiderman's uncle Cliff Robertson said: with great
>> power comes great responsibility.
>>>> I am now firmly in the "using __signature__ as a cache is fine, don't make
>> copies for no reason" camp.
>> I have a simpler rule: functions in the inspect module should not have
> side effects on the objects they're used to inspect.
>> When I call "inspect.signature(f)", I expect to get something I can
> modify without affecting the state of "f". That means, even if
> f.__signature__ is set, the signature function will need to return a
> copy rather than a direct reference to the original. If
> f.__signature__ is going to be copied *anyway*, then there's no reason
> to cache it, *unless* we want to say something other than what the
> inspect module would automatically derive from other attributes like
> __func__, __wrapped__, __call__, __code__, __closure__, etc.

There is still a potential reason to cache func.__signature__: it's a 
relatively large chunk of fields, which duplicates a lot of already existing 
data. Why make all function objects bigger when only a small minority will be 
inspected for their __signature__?
I think that lazy evaluation of __signature__ is desirable, and caching it is 
certainly desirable now that you have convinced me that there are use-cases 
for setting __signature__.
Perhaps func.__signature__ should be a computed the first time it is accessed? 
Something conceptually like this:
class FunctionWithSignature(types.FunctionType):
 @property
 def __signature__(self):
 if hasattr(self._sig):
 return self._sig
 sig = self._get_signature() # Left as an exercise for the reader.
 self._sig = sig
 return sig
 @__signature__.setter
 def __signature__(self, sig):
 self._sig = sig
 @__signature__.deleter
 def __signature__(self):
 del self._sig
-- 
Steven


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /