Michael Howitz wrote:
Am 14.12.2007 um 01:29 schrieb Jeremy Roberts:
Hello zope3 users!

I'm using Zope-3.3.1, and I'm trying to expose a method via xmlrpc and I'm having trouble supporting a variable number of kwargs. My use case does not know ahead of time how many arguments will be passed to the method, hence the use of **kwargs in the method signature.

I get the error:
Unexpected Zope exception: TypeError: renderCode() takes at most 1 argument (2 given).


Hi!

I think this is because XML-RPC does not support (optional) keyword arguments, you only may use positional arguments. A solution for optional arguments can be a dictionary containing the optional arguments for your XML-RPC-View as the last parameter. But this parameter is not optional itself.

So your view could look like:

class ToolCodeXMLRPC(MethodPublisher):
   """An XMLRPC view for ToolCode objects."""

   def renderCode(self, data):
       return self.context.renderCode(**data)




Thanks a ton Michael.
This suggestion ultimately led to a solution.

First I changed my XMLRPC view method signature to expect a positional dictionary per your suggestion.

This led to another problem: my XML was passing a <struct> representing a dictionary of params which was being unmarshalled from XML to method call by Zope as keyword arguments - this resulted in an "Unexpected keyword argument: 'color'" error.

In other words, the XML below is converted into a method call like so:
renderCode(color='green', number='3')

<?xml version="1.0"?>
<methodCall>
<methodName>renderCode</methodName>
<params>

<param>
<value>
<struct>
<member><name>color</name><value><string>green</string></value></member>
<member><name>number</name><value><string>3</string></value></member>
</struct>
</value>
</param>

</params>
</methodCall>



The fix was to pack my data struct into another struct with an explicit keyword:

<?xml version="1.0"?>
<methodCall>
<methodName>renderCode</methodName>

<params>

<param>
<value>

<struct>
<member><name>data</name><value>

<struct>
<member><name>color</name><value><string>fuscia</string></value></member>
<member><name>number</name><value><string>3</string></value></member>
</struct>

</value>
</member>
</struct>
</value>
</param>

</params>
</methodCall>


(Note the nested struct.) This is converted into a method call like so:
renderCode(data={color: 'fuscia', number: '3'})

This worked like a charm. Thanks for all the help o mighty list - for I now declare this code to be totally awesome.

-Jer

PS: 'fuscia' simply CAN'T be the correct spelling.
_______________________________________________
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users

Reply via email to