On Wed, Jun 6, 2012 at 12:51 PM, Yury Selivanov <yselivanov...@gmail.com> wrote: > As for moving Signature object to `functools`, we had this discussion with > Brett, and here is what he suggested: > > Functools contains code that transforms what a function > does while inspect is about introspection. These objects are > all about introspection and not about transforming what a > function does.
I actually disagree with that characterisation of the new feature, as: 1. __signature__ introduces the possibility for a function (or any object, really) to say "this is my *real* signature, even if the lower level details appear to be more permissive than that" 2. Signature.bind introduces the ability to split the "bind arguments to parameters" operation from the "call object" operation Those two use cases are about function manipulation rather than pure introspection, making functools an appropriate home. >> - "functools.update_wrapper" be enhanced to set "wrapper.__signature__ >> = signature(wrapped)" > > Big +1 on this one. If you give me a green light on this, I'll add this > change along with the unit tests to the patch. And this is actually the real reason I'm proposing functools as the home for the new feature. I think this change would a great enhancement to functools.wraps, but I also think making functools depend on the inspect module would be a crazy thing to do :) However, looking at the code, I think the split that makes sense is for a lower level functools.signature to *only* support real function objects (i.e. not even method objects). At the inspect layer, inspect.signature could then support retrieving a signature for an arbitrary callable roughly as follows: def signature(f): try: # Real functions are handled directly by functools return functools.signature(f) except TypeError: pass # Not a function object, handle other kinds of callable if isclass(f): # Figure out a Signature based on f.__new__ and f.__init__ # Complain if the signatures are contradictory # Account for the permissive behaviour of object.__new__ and object.__init__ return class_signature if ismethod(f): f = f.__func__ elif not isfunction(f): try: f = f.__call__ except AttributeError: pass return signature(f) # Use recursion for the initial implementation sketch That code is almost certainly wrong, but it should be enough to give the general idea. The short version is: 1. Provide a functools.signature that expects ordinary function objects (or objects with a __signature__ attribute) 2. Provide an inspect.signature that also handles other kinds of callable Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com