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

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) >>> boundargs = signature(foo).bind(1, 2, 3) >>> boundargs.arguments OrderedDict([('args', (1, 2, 3))]) You can't invoke 'foo' by: >>> foo(**boundargs.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().

>>> boundargs.args, boundargs.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.



More information about the Python-Dev mailing list