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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4