[Freeipa-devel] argument passing

Rob Crittenden rcritten at redhat.com
Wed Aug 22 15:13:59 UTC 2007


My last ugly patch was an attempt to get around a particularly nasty 
problem.

When passing arguments in XML-RPC (as handled by python) the arguments 
are put into a tuple before being passed into the receiving function.

Additionally we stick in our own argument, opts, which is a dict 
contains anything the web server might want to include (like the 
kerberos principal name of the client).

So we end up calling functions with:  ret = func(*params, **opts)

One can also call these same functions directly which is what TurboGears 
will do. x = find_user(...)

So how to handle the arguments is not obvious, particularly optional 
ones. The argument name is not included in the XML-RPC request, just the 
data type and value(s). So how do we know which argument is which when 
there are optional ones?

And one last tidbit, None is not an acceptable value in XML-RPC. There 
are hacks which allow it but not every client supports it (gets 
transported as the value null). I think we should avoid enabling this if 
possible.

So what my hack was attempting to do was given how many arguments the 
function required, figure out how many arguments were in the tuple and 
extract them, tacking opts onto the end (opts is ALWAYS the last argument).

The problem is optional arguments. Things will blow up if optional 
arguments are empty.

One solution is to require a value for every argument over XML-RPC. We 
could either send "" in place of None or come up with our own None 
string, like __NONE__.

Additionally, this argument re-ordering could be moved into the XML-RPC 
server instead so the function is called "normally" and no argument 
munging is needed in funcs.py.

This too would be quite ugly, though I believe less ugly than my current 
solution. We'd have to do something like:

arglen = len(params)

if arglen == 1:
     ret = func(params[0], opts)
elif arglen == 2:
     ret = func(params[0], params[1], opts)
elif arglen == 3:
     ret = func(params[0], params[1], params[2], opts)
...

This will leave us in a "gee, they'll never need more than N arguments" 
but it is trivial to fix.

This is way less horrible IMHO but still limiting. There may even be a 
clever way to replace "" or __NONE__ with None in params before calling. 
I'd do something like:

for i in range(len(params)):
   if params[i] == '':
       params[i] = None

This keeps funcs.py more independent of implementation.

Thoughts?

rob
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3245 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://listman.redhat.com/archives/freeipa-devel/attachments/20070822/71106ee0/attachment.bin>


More information about the Freeipa-devel mailing list