[Python-Dev] signature object issues (to discuss while I am out of contact)
Brett Cannon
brett at python.org
Tue May 2 20:43:56 CEST 2006
On 5/2/06, Nick Coghlan <ncoghlan at gmail.com> wrote:
> Brett Cannon wrote:
> > One is whether a signature object should be automatically created for
> > every function. As of right now the PEP I am drafting has it on a
> > per-need basis and have it assigned to __signature__ through a
> > built-in function or putting it 'inspect'. Now automatically creating
> > the object would possibly make it more useful, but it could also be
> > considered overkill. Also not doing it automatically allows signature
> > objects to possibly make more sense for classes (to represent
> > __init__) and instances (to represent __call__). But having that same
> > support automatically feels off for some reason to me.
>
> My current impulse is to put the signature object in the inspect module to
> start with, and don't give it a special attribute at all.
>
> All of the use cases I can think of (introspection for documentation purposes
> or argument checking purposes) don't really suffer either way regardless of
> whether the signature retrieval is spelt "obj.__signature__" or
> "inspect.getsignature(obj)".
>
It does for decorators. How do you make sure that a decorator uses
the signature object of the wrapped function instead of the decorator?
Or are you saying to just not worry about that right now?
> Since it doesn't make much difference from a usability point of view, let's
> start with the object in the library module first.
>
> > The second question is whether it is worth providing a function that
> > will either figure out if a tuple and dict representing arguments
> > would work in calling the function. Some have even suggested a
> > function that returns the actual bindings if the call were to occur.
> > Personally I don't see a huge use for either, but even less for the
> > latter version. If people have a legit use case for either please
> > speak up, otherwise I am tempted to keep the object simple.
>
> A "bind" method on the signature objects is pretty much essential for any kind
> of argument checking usage.
>
> In addition to Aahz's precondition checking example, Talin gave a good example
> on the Py3k list of a function decorator for logging all calls to a function,
> and including the argument bindings in the log message.
>
> And just in case you think the operation would be easy to implement if you
> need it, I've included below the bind method from the signature object I wrote
> to play around with the ideas posted to the Py3k list. It took a fair bit of
> work to get it to spit out the right answers :)
>
Thanks, Nick!
-Brett
> Cheers,
> Nick.
>
> def bind(*args, **kwds):
> """Return a dict mapping parameter names to bound arguments"""
> self = args[0]
> args = args[1:]
> bound_params = {}
> num_args = len(args)
> missing_args = set(self.required_args)
> arg_names = self.required_args + self.optional_args
> num_names = len(arg_names)
> # Handle excess positional arguments
> if self.extra_args:
> bound_params[self.extra_args] = tuple(args[num_names:])
> elif num_args > num_names:
> self._raise_args_error(num_args)
> # Bind positional arguments
> for name, value in zip(arg_names, args):
> bound_params[name] = value
> missing_args -= set((name,))
> # Bind keyword arguments (and handle excess)
> if self.extra_kwds:
> extra_kwds = dict()
> bound_params[self.extra_kwds] = extra_kwds
> else:
> extra_kwds = None
> for name, value in kwds.items():
> if name in bound_params:
> raise TypeError(
> "Got multiple values for argument '%s'" % name)
> elif name in arg_names:
> missing_args -= set((name,))
> bound_params[name] = value
> elif extra_kwds is not None:
> extra_kwds[name] = value
> else:
> raise TypeError(
> "Got unexpected keyword argument '%s'" % name)
> if missing_args:
> self._raise_args_error(num_args)
> # All done
> return bound_params
>
>
> --
> Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
> ---------------------------------------------------------------
> http://www.boredomandlaziness.org
>
More information about the Python-Dev
mailing list