[Python-Dev] Updated PEP 362 (Function Signature Object)

Daniel Urban urban.dani+py at gmail.com
Thu Jun 7 06:44:56 CEST 2012


On Wed, Jun 6, 2012 at 10:10 PM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
> On 2012年06月06日, at 3:33 PM, Daniel Urban wrote:
>> On Wed, Jun 6, 2012 at 8:35 PM, Yury Selivanov <yselivanov.ml at 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)

I see. Thanks, this modifying example is the first convincing use case
I hear. Maybe it would be good to mention something like this in the
PEP.
Daniel


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /