[Python-Dev] Updated PEP 362 (Function Signature Object)
Yury Selivanov
yselivanov.ml at gmail.com
Wed Jun 6 20:35:51 CEST 2012
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().
>> >>> bound_args.args, bound_args.kwargs
>> ((1, 2, 3), {})
>>
>> 'BoundArguments.arguments', as told in the PEP, is a mapping to work
>> with 'Signature.parameters' (you should've seen it in the
>> "Annotation Checker" example).
>>
>> 'args' & 'kwargs' are for invocation. You can even modify 'arguments'.
>>
>>>> Has the following public attributes:
>>>>
>>>> * arguments : OrderedDict
>>>> An ordered mutable mapping of parameters' names to arguments' values.
>>>> Does not contain arguments' default values.
>>>
>>> Does this mean, that if the arguments passed to bind doesn't contain a
>>> value for an argument that has a default value, then the returned
>>> mapping won't contain that argument? If so, why not?
>>> inspect.getcallargs works fine with default values.
>>
>> Yes, it won't. It contains only arguments you've passed to the 'bind'.
>> The reason is because we'd like to save as much of actual context as
>> possible.
>
> I don't really see, where this "context" can be useful. Maybe an
> example would help.
For instance, for some sort of RPC mechanism, where you don't need to
store/pass arguments that have default values.
>> If you pass some set of arguments to the bind() method, it tries to map
>> precisely that set. This way you can deduce from the BoundArguments what
>> it was bound with. And default values will applied by python itself.
>
> Anyway, I think it would be nice to be able to obtain the full
> arguments mapping that the function would see, not just a subset. Of
> course, we can use inspect.getcallargs for that, but I think we should
> be able to do that with the new Signature API.
Well, it will take just a few lines of code to enrich BoundArguments with
default values (we can add a method to do it, if it's really that required
feature). But you won't be able to ever reconstruct what arguments the
bind() method was called with, if we write default values to arguments
from start.
Also, it's better for performance. "Annotation Checker" example does
defaults validation first, and never checks them again. If bind() would
write default values to 'BoundArguments.arguments', you would check
defaults on each call. And think about more complicated cases, where
processing of argument's value is more complicated and time consuming.
All in all, I consider the way 'inspect.getcallargs' treats defaults
as a weakness, not as an advantage.
-
Yury
More information about the Python-Dev
mailing list