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

Alexandre Zani alexandre.zani at gmail.com
Fri Jun 8 06:20:37 CEST 2012


A comment on the way methods are handled. I have seen decorators that do something like this:

import functools

def dec(f): functools.wraps(f) def decorated(*args, *kwargs): cursor = databaseCursor() return f(cursor, *args, **kwargs)

As a result, if the decorated function has to be something like this:

class SomeClass(object): @dec def func(cursor, self, whatever): ...

Perhaps the decorator should be smarter about this and detect the fact that it's dealing with a method but right now, the Signature object would drop the first argument (cursor) which doesn't seem right. Perhaps the decorator should set signature. I'm not sure.

On Thu, Jun 7, 2012 at 9:04 PM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:

Nick,

I'm replying to your email (re 'functools.partial') in python-ideas here, in the PEP 362 thread, as my response raises some questions regarding its design.

On 2012-06-07, at 11:40 PM, Nick Coghlan wrote: On Fri, Jun 8, 2012 at 12:57 PM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:

Hello,

While I was working on adding support for 'functools.partial' in PEP 362, I discovered that it doesn't do any sanity check on passed arguments upon creation. Example:  def foo(a):  pass  p = partial(foo, 1, 2, 3) # this line will execute  p() # this line will fail Is it a bug?  Or is it a feature, because we deliberately don't do any checks because of performance issues?  If the latter - I think it should be at least documented. Partly the latter, but also a matter of "this is hard to do, so we don't even try". There are many other "lazy execution" APIs with the same problem - they accept an arbitrary underlying callable, but you don't find out until you try to call it that the arguments don't match the parameters. This leads to errors being raised far away from the code that actually introduced the error. If you dig up some of the older PEP 362 discussions, you'll find that allowing developers to reduce this problem over time is the main reason the Signature.bind() method was added to the PEP. While I wouldn't recommend it for the base partial type, I could easily see someone using PEP 362 to create a "checked partial" that ensures arguments are valid as they get passed in rather than leaving the validation until the call is actually made. It's not going to be that easy with the current PEP design. In order to add support for partial, I had to split the implementation of 'bind' into two functions:  def bind(self, args, kwargs, *, partial=False):  ...  def bind(self, *args, **kwargs):  return self.bind(args, kwargs) The first one, 'bind' does all the hard work.  When 'partial' flag is False - it performs all possible checks.  But if it's 'True', then it allows you to bind arguments in the same way 'functools.partial' works, but still with most of the validation. So:  def foo(a, b, c):  pass  sig = signature(foo)  sig.bind((1, 2, 3, 4), partial=True) # <- this will fail  sig.bind((1, 2), partial=True) # <- this is OK  sig.bind((1, 2), partial=False) # <- this will fail too But the problem is - 'bind' is an implementation detail. I'd like to discuss changing of PEP 362 'bind' signature to match the 'bind' method. This will make API less nice, but will allow more. Or, we can add something like 'bindex' (in addition to 'bind'). - Yury


Python-Dev mailing list Python-Dev at python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/alexandre.zani%40gmail.com



More information about the Python-Dev mailing list