[Zope-dev] XMLRPC with varargs

Marco Catunda catunda@embratel.net.br
17 Mar 2003 19:39:25 -0300


Hello, 

I have tried call a function via XMLRPC with * and ** args 
with no success! 

The following error have appeared: 

------------------------------------------------ 
Unexpected Zope error value: 
Traceback (most recent call last): 
  File
"/home/catunda/projetos/zope/cvs/zope/lib/python/ZPublisher/Publish.py",
line 150, in publish_module 
    response = publish(request, module_name, after_list, debug=debug) 
  File
"/home/catunda/projetos/zope/cvs/zope/lib/python/ZPublisher/Publish.py",
line 114, in publish 
    sys.exc_info()[2], 
  File
"/home/catunda/projetos/zope/cvs/zope/lib/python/ZPublisher/Publish.py",
line 98, in publish 
    request, bind=1) 
  File
"/home/catunda/projetos/zope/cvs/zope/lib/python/ZPublisher/mapply.py",
line 71, in mapply 
    if len(positional) > nargs: raise TypeError, 'too many arguments' 
TypeError: too many arguments 
------------------------------------------------ 



I don't know if it's a bug but I debugged zope and changed 
some things in mapply.py. The idea of this changes is 
test if a function has *,** args or not using inspect 
module. I don't know if this changes will affect other 
things in zope. 

Follow the patch of changes.

--- mapply.py	2003-03-17 19:30:12.000000000 -0300
+++ mapply.py.new	2003-03-17 18:59:54.000000000 -0300
@@ -13,6 +13,8 @@
 """Provide an apply-like facility that works with any mapping object
 """
 
+import inspect
+
 def default_call_object(object, args, context):
     result=apply(object,args) # Type s<cr> to step into published object.
     return result
@@ -23,11 +25,15 @@
 def default_handle_class(klass, context):
     if hasattr(klass,'__init__'):
         f=klass.__init__.im_func
-        c=f.func_code
-        names=c.co_varnames[1:c.co_argcount]
-        return klass, names, f.func_defaults
+        #c=f.func_code
+        #names=c.co_varnames[1:c.co_argcount]
+        spec=inpect.getargspec(f)
+        names=spec[0][1:]
+        defaults=spec[3]
+        vargs=spec[1:3]
+        return klass, names, defaults, vargs
     else:
-        return klass, (), ()
+        return klass, (), (), []
 
 def mapply(object, positional=(), keyword={},
            debug=None, maybe=None,
@@ -37,7 +43,7 @@
            ):
 
     if hasattr(object,'__bases__'):
-        f, names, defaults = handle_class(object, context)
+        f, names, defaults, vargs = handle_class(object, context)
     else:
         f=object
         im=0
@@ -53,20 +59,28 @@
 
         if im:
             f=f.im_func
-            c=f.func_code
-            defaults=f.func_defaults
-            names=c.co_varnames[1:c.co_argcount]
+            #c=f.func_code
+            #defaults=f.func_defaults
+            #names=c.co_varnames[1:c.co_argcount]
+            spec=inspect.getargspec(f)
+            names=spec[0][1:]
+            defaults=spec[3]
+            vargs=spec[1:3]
         else:
             defaults=f.func_defaults
-            c=f.func_code
-            names=c.co_varnames[:c.co_argcount]
+            #c=f.func_code
+            #names=c.co_varnames[:c.co_argcount]
+            spec=inspect.getargspec(f)
+            names=spec[0]
+            defaults=spec[3]
+            vargs=spec[1:3]
 
     nargs=len(names)
     if positional:
         positional=list(positional)
         if bind and nargs and names[0]=='self':
             positional.insert(0, missing_name('self', context))
-        if len(positional) > nargs: raise TypeError, 'too many arguments'
+        if (len(positional) > nargs) and not vargs: raise TypeError, 'too many arguments'
         args=positional
     else:
         if bind and nargs and names[0]=='self':


--
Marco Catunda