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...@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...@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 'bind_ex' (in addition to 'bind'). > > - > Yury > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/alexandre.zani%40gmail.com _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com