[Python-Dev] Updated PEP 362 (Function Signature Object)
Daniel Urban
urban.dani+py at gmail.com
Wed Jun 6 20:22:26 CEST 2012
>>> BoundArguments Object
>>> =====================
>>>
>>> Result of a ``Signature.bind`` call. Holds the mapping of arguments
>>> to the function's parameters.
>>
>> The Signature.bind function has changed since the previous version of
>> the PEP. If I understand correctly, the 'arguments' attribute is the
>> same as the return value of bind in the previous version (more or less
>> the same as the return value of inspect.getcallargs). My question is:
>> why we need the other 2 attributes ('args' and 'kwargs')? The
>> "Annotation Checker" example uses it to call the function. But if we
>> are able to call bind, we already have the arguments, so we can simply
>> call the function with them, we don't really need these attributes. I
>> think it would be better (easier to use and understand), if bind would
>> simply return the mapping, as in the previous version of the PEP.
>
> 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.
> 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.
> >>> 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.
> 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.
Daniel
More information about the Python-Dev
mailing list