Add a new parameter 'ignore_extra_args' to the @signature decorator (and its frontends @wsexpose)

This commit is contained in:
Christophe de Vienne 2012-12-19 15:11:52 +01:00
parent 73afdb0a87
commit 76bfc4cc70
5 changed files with 41 additions and 9 deletions

View File

@ -66,6 +66,11 @@ class FunctionDefinition(object):
#: If the body carry the datas of a single argument, its type #: If the body carry the datas of a single argument, its type
self.body_type = None self.body_type = None
#: True if extra arguments should be ignored, NOT inserted in
#: the kwargs of the function and not raise UnknownArgument
#: exceptions
self.ignore_extra_args = False
#: Dictionnary of protocol-specific options. #: Dictionnary of protocol-specific options.
self.extra_options = None self.extra_options = None
@ -94,8 +99,9 @@ class FunctionDefinition(object):
for arg in self.arguments: for arg in self.arguments:
arg.resolve_type(registry) arg.resolve_type(registry)
def set_options(self, body=None, **extra_options): def set_options(self, body=None, ignore_extra_args=False, **extra_options):
self.body_type = body self.body_type = body
self.ignore_extra_args = ignore_extra_args
self.extra_options = extra_options self.extra_options = extra_options
def set_arg_types(self, argspec, arg_types): def set_arg_types(self, argspec, arg_types):

View File

@ -172,7 +172,7 @@ def args_from_params(funcdef, params):
kw[argdef.name] = value kw[argdef.name] = value
paths = set(params.keys()) paths = set(params.keys())
unknown_paths = paths - hit_paths unknown_paths = paths - hit_paths
if unknown_paths: if not funcdef.ignore_extra_args and unknown_paths:
raise UnknownArgument(', '.join(unknown_paths)) raise UnknownArgument(', '.join(unknown_paths))
return [], kw return [], kw
@ -195,9 +195,13 @@ def args_from_body(funcdef, body, mimetype):
else: else:
raise ValueError("Unknow mimetype: %s" % mimetype) raise ValueError("Unknow mimetype: %s" % mimetype)
kw = dataformat.parse( try:
body, datatypes, bodyarg=funcdef.body_type is not None kw = dataformat.parse(
) body, datatypes, bodyarg=funcdef.body_type is not None
)
except UnknownArgument:
if not funcdef.ignore_extra_args:
raise
return (), kw return (), kw

View File

@ -202,10 +202,14 @@ def parse(s, datatypes, bodyarg):
kw = {argname: fromjson(datatypes[argname], jdata)} kw = {argname: fromjson(datatypes[argname], jdata)}
else: else:
kw = {} kw = {}
extra_args = []
for key in jdata: for key in jdata:
if key not in datatypes: if key not in datatypes:
raise UnknownArgument(key) extra_args.append(key)
kw[key] = fromjson(datatypes[key], jdata[key]) else:
kw[key] = fromjson(datatypes[key], jdata[key])
if extra_args:
raise UnknownArgument(', '.join(extra_args))
return kw return kw

View File

@ -232,10 +232,13 @@ def parse(s, datatypes, bodyarg):
return fromxml(datatypes[name], tree) return fromxml(datatypes[name], tree)
else: else:
kw = {} kw = {}
extra_args = []
for sub in tree: for sub in tree:
if sub.tag not in datatypes: if sub.tag not in datatypes:
raise UnknownArgument(sub.tag) extra_args.append(sub.tag)
kw[sub.tag] = fromxml(datatypes[sub.tag], sub) kw[sub.tag] = fromxml(datatypes[sub.tag], sub)
if extra_args:
raise UnknownArgument(', '.join(extra_args))
return kw return kw

View File

@ -108,7 +108,7 @@ class MiniCrud(object):
print(repr(data)) print(repr(data))
return CRUDResult(data, u('create')) return CRUDResult(data, u('create'))
@expose(CRUDResult, method='GET') @expose(CRUDResult, method='GET', ignore_extra_args=True)
@validate(Obj) @validate(Obj)
def read(self, ref): def read(self, ref):
print(repr(ref)) print(repr(ref))
@ -382,3 +382,18 @@ class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
assert result['data']['id'] == 1 assert result['data']['id'] == 1
assert result['data']['name'] == u("test") assert result['data']['name'] == u("test")
assert result['message'] == "delete" assert result['message'] == "delete"
def test_extra_arguments(self):
headers = {
'Content-Type': 'application/json',
}
res = self.app.get(
'/crud?ref.id=1&extraarg=foo',
headers=headers,
expect_errors=False)
print("Received:", res.body)
result = json.loads(res.text)
print(result)
assert result['data']['id'] == 1
assert result['data']['name'] == u("test")
assert result['message'] == "read"