use inspect module to report/check rpc args

This commit is contained in:
Mike McLean 2012-04-17 23:37:58 -04:00
parent 38f7d2529f
commit 2c372cd5f0
3 changed files with 48 additions and 12 deletions

View file

@ -2382,17 +2382,20 @@ def anon_handle_list_api(options, session, args):
tmplist.sort()
funcs = [x[1] for x in tmplist]
for x in funcs:
if x['args']:
if 'argdesc' in x:
args = x['argdesc']
elif x['args']:
# older servers may not provide argdesc
expanded = []
for arg in x['args']:
if type(arg) is str:
expanded.append(arg)
else:
expanded.append('%s=%s' % (arg[0], arg[1]))
args = ", ".join(expanded)
args = "(%s)" % ", ".join(expanded)
else:
args = ""
print '%s(%s)' % (x['name'], args)
args = "()"
print '%s%s' % (x['name'], args)
if x['doc']:
print " description: %s" % x['doc']

View file

@ -19,6 +19,7 @@
# Mike McLean <mikem@redhat.com>
from ConfigParser import RawConfigParser
import inspect
import logging
import os
import sys
@ -104,8 +105,11 @@ class HandlerRegistry(object):
#the keys in self.funcs determine the name of the method as seen over xmlrpc
#func.__name__ might differ (e.g. for dotted method names)
args = self._getFuncArgs(func)
argspec = inspect.getargspec(func)
funcs.append({'name': name,
'doc': func.__doc__,
'argspec': tuple(argspec),
'argdesc': inspect.formatargspec(*argspec),
'args': args})
return funcs
@ -131,13 +135,8 @@ class HandlerRegistry(object):
func = self.funcs.get(method)
if func is None:
return ""
arglist = []
for arg in self._getFuncArgs(func):
if isinstance(arg,str):
arglist.append(arg)
else:
arglist.append('%s=%s' % (arg[0], arg[1]))
ret = '%s(%s)' % (method, ", ".join(arglist))
args = inspect.formatargspec(*inspect.getargspec(func))
ret = '%s%s' % (method, args)
if func.__doc__:
ret += "\ndescription: %s" % func.__doc__
return ret
@ -246,7 +245,36 @@ class ModXMLRPCRequestHandler(object):
if not context.session.hasPerm('admin'):
raise koji.ServerOffline, "Server disabled for maintenance"
# handle named parameters
params,opts = koji.decode_args(*params)
params, opts = koji.decode_args(*params)
#check args against the function
f_args, f_varargs, f_varkw, f_defaults = inspect.getargspec(func)
if not f_varargs:
if f_varkw:
n_given = len(params)
else:
n_given = len(params) + len(opts)
if n_given > len(f_args):
raise koji.ParameterError, "%s() takes %i fixed arguments (%i given)" \
% (method, len(f_args), n_given)
data = dict(zip(f_args, params))
for arg in opts:
if not f_varkw and arg not in f_args:
raise koji.ParameterError, "%s() got an unexpected keyword argument %r" \
% (method, arg)
if arg in data:
raise koji.ParameterError, "%s() got a duplicate keyword argument %r" \
% (method, arg)
else:
data[arg] = opts[arg]
if f_defaults:
for arg, val in f_defaults:
data.setdefault(arg, val)
for n, arg in enumerate(f_args):
if arg not in data:
# missing arg
raise koji.ParameterError, "%s() missing required argument %r (#%i)" \
% (method, arg, n)
if self.logger.isEnabledFor(logging.INFO):
self.logger.info("Handling method %s for session %s (#%s)",

View file

@ -310,6 +310,11 @@ class ApplianceError(GenericError):
"""Raised when Appliance Image creation fails"""
faultCode = 1018
class ParameterError(GenericError):
"""Raised when an rpc call receives incorrect arguments"""
faultCode = 1019
class MultiCallInProgress(object):
"""
Placeholder class to be returned by method calls when in the process of