From 47ca5f17737155a64d0b98466ecef496db3039ef Mon Sep 17 00:00:00 2001 From: Vincent Pelletier <vincent@nexedi.com> Date: Fri, 8 Mar 2013 15:12:47 +0100 Subject: [PATCH] Fix magic "self" parameter detection. Original code behaviour: >>> def foo(self, a=None): ... return 'works' ... >>> context.foo(a=1) works >>> def foo(self, a): ... return 'works' ... >>> context.foo(1) works >>> context.foo(a=1) TypeError: foo() takes exactly 2 non-keyword arguments (0 given) New behaviour fixes this TypeError, to be closer to normal python behaviour. Also, original code was doing expensive checks before cheap ones. --- product/ERP5Type/patches/ExternalMethod.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/product/ERP5Type/patches/ExternalMethod.py b/product/ERP5Type/patches/ExternalMethod.py index a7e2768f89..fcb6d8ab57 100644 --- a/product/ERP5Type/patches/ExternalMethod.py +++ b/product/ERP5Type/patches/ExternalMethod.py @@ -11,6 +11,7 @@ # ############################################################################## +from inspect import getargspec from Products.ExternalMethod.ExternalMethod import * if 1: @@ -65,6 +66,8 @@ if 1: Component Extension if available, otherwise fallback on filesystem Extension - access volatile attribute safely + - fix magic "self" argument when positional arguments get their values + from kw. """ try: f = getattr(__import__('erp5.component.extension.' + self._module, @@ -103,9 +106,13 @@ if 1: except TypeError, v: tb=sys.exc_info()[2] try: - if ((self._v_func_code.co_argcount- - len(self._v_func_defaults or ()) - 1 == len(args)) - and self._v_func_code.co_varnames[0]=='self'): + func_args, func_varargs, _, func_defaults = getargspec(f) + by_kw = set(kw) + if func_defaults: + by_kw.update(func_args[-len(func_defaults):]) + if func_args[0] == 'self' and 'self' not in kw and ( + func_varargs or len(set(func_args[len(args):] + ).difference(by_kw)) == 1): return f(self.aq_parent.this(), *args, **kw) raise TypeError, v, tb -- 2.30.9