On 5/2/06, Nick Coghlan <[EMAIL PROTECTED]> 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 | [EMAIL PROTECTED] | Brisbane, Australia > --------------------------------------------------------------- > http://www.boredomandlaziness.org > _______________________________________________ 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