On 2012-06-06, at 3:33 PM, Daniel Urban wrote: > On Wed, Jun 6, 2012 at 8:35 PM, Yury Selivanov <yselivanov...@gmail.com> > wrote: >> On 2012-06-06, at 2:22 PM, Daniel Urban wrote: >>>> I'll try to answer you with the following code: >>>> >>>> >>> def foo(*args): >>>> ... print(args) >>>> >>>> >>> bound_args = signature(foo).bind(1, 2, 3) >>>> >>> bound_args.arguments >>>> OrderedDict([('args', (1, 2, 3))]) >>>> >>>> You can't invoke 'foo' by: >>>> >>>> >>> foo(**bound_args.arguments) >>>> TypeError: foo() got an unexpected keyword argument 'args' >>> >>> Of course, but you can invoke it with "1, 2, 3", the arguments you >>> used to create the BoundArguments instance in the first place: foo(1, >>> 2, 3) will work fine. >> >> The whole point is to use BoundArguments mapping for invocation. >> See Nick's idea to validate callbacks, and my response to him, below in >> the thread. >> >>>> That's why we have two dynamic properties 'args', and 'kwargs': >>> >>> Ok, but what I'm saying is, that we don't really need them. >> >> We need them. Again, in some contexts you don't have the arguments >> you've passed to bind(). > > But how could we *need* bind to return 'args' and 'kwargs' to us, when > we wouldn't be able to call bind in the first place, if we wouldn't > had the arguments?
You're missing the point. BoundArguments contains properly mapped *args and **kwargs passed to Signature.bind. You can validate them after, do type casts, modify them, overwrite etc. by manipulating 'BoundArguments.arguments'. At the end you can't, however, invoke the function by doing: func(**bound_arguments.arguments) # <- this won't work as varargs will be screwed. That's why you need 'args' & 'kwargs' properties on BoundArguments. Imagine, that "Annotation Checker" example is modified to coerce all string arguments to int (those that had 'int' in annotation) and then to multiply them by 42. We'd write the following code: for arg_name, arg_value in bound_arguments.arguments.items(): # I'm skipping is_args & is_kwargs checks, and assuming # we have annotations everywhere if sig.parameters[arg_name].annotation is int \ and isinstance(arg_value, str): bound_arguments.arguments[arg_name] = int(arg_value) * 42 return func(*bound_arguments.args, **bound_arguments.kwargs) Thanks, - Yury _______________________________________________ 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