Merge pull request #175 from kgriffs/issues/154
fix(Request.get_param_as_list): Handle missing list items
This commit is contained in:
@@ -549,7 +549,9 @@ class Request(object):
|
||||
name: Parameter name, case-sensitive (e.g., 'limit')
|
||||
transform: An optional transform function that takes as input
|
||||
each element in the list as a string and outputs a transformed
|
||||
element for inclusion in the list that will be returned.
|
||||
element for inclusion in the list that will be returned. For
|
||||
example, passing the int function will transform list items
|
||||
into numbers.
|
||||
required: Set to True to raise HTTPBadRequest instead of returning
|
||||
gracefully when the parameter is not found or is not an
|
||||
integer (default False)
|
||||
@@ -558,21 +560,43 @@ class Request(object):
|
||||
|
||||
Returns:
|
||||
The value of the param if it is found. Otherwise, returns None
|
||||
unless required is True.
|
||||
unless required is True. for partial lists, None will be returned
|
||||
as a placeholder. For example:
|
||||
|
||||
things=1,,3
|
||||
|
||||
would be returned as:
|
||||
|
||||
['1', None, '3']
|
||||
|
||||
while this:
|
||||
|
||||
things=,,,
|
||||
|
||||
would just be retured as:
|
||||
|
||||
[None, None, None, None]
|
||||
|
||||
Raises
|
||||
HTTPBadRequest: The param was not found in the request, but was
|
||||
required.
|
||||
|
||||
"""
|
||||
|
||||
# PERF: Use if..in since it is a good all-around performer; we don't
|
||||
# know how likely params are to be specified by clients.
|
||||
if name in self._params:
|
||||
items = self._params[name].split(',')
|
||||
if transform is not None:
|
||||
|
||||
# PERF(kgriffs): Use if-else rather than a DRY approach
|
||||
# that sets transform to a passthrough function; avoids
|
||||
# function calling overhead.
|
||||
if transform is None:
|
||||
items = [i if i != '' else None
|
||||
for i in items]
|
||||
else:
|
||||
try:
|
||||
items = [transform(x) for x in items]
|
||||
items = [transform(i) if i != '' else None
|
||||
for i in items]
|
||||
except ValueError:
|
||||
desc = ('The value of the "' + name + '" query parameter '
|
||||
'is not formatted correctly.')
|
||||
|
||||
@@ -181,7 +181,9 @@ class TestQueryParams(testing.TestBase):
|
||||
self.assertEquals(store['echo'], True)
|
||||
|
||||
def test_list_type(self):
|
||||
query_string = 'colors=red,green,blue&limit=1'
|
||||
query_string = ('colors=red,green,blue&limit=1'
|
||||
'&list-ish1=f,,x&list-ish2=,0&list-ish3=a,,,b'
|
||||
'&empty1=&empty2=,&empty3=,,')
|
||||
self.simulate_request('/', query_string=query_string)
|
||||
|
||||
req = self.resource.req
|
||||
@@ -191,12 +193,27 @@ class TestQueryParams(testing.TestBase):
|
||||
self.assertEquals(req.get_param_as_list('limit'), ['1'])
|
||||
self.assertIs(req.get_param_as_list('marker'), None)
|
||||
|
||||
self.assertEquals(req.get_param_as_list('empty1'), None)
|
||||
self.assertEquals(req.get_param_as_list('empty2'), [None, None])
|
||||
self.assertEquals(req.get_param_as_list('empty3'), [None, None, None])
|
||||
|
||||
self.assertEquals(req.get_param_as_list('list-ish1'),
|
||||
['f', None, 'x'])
|
||||
|
||||
# Ensure that '0' doesn't get translated to None
|
||||
self.assertEquals(req.get_param_as_list('list-ish2'),
|
||||
[None, '0'])
|
||||
|
||||
# Ensure that '0' doesn't get translated to None
|
||||
self.assertEquals(req.get_param_as_list('list-ish3'),
|
||||
['a', None, None, 'b'])
|
||||
|
||||
store = {}
|
||||
self.assertEquals(req.get_param_as_list('limit', store=store), ['1'])
|
||||
self.assertEquals(store['limit'], ['1'])
|
||||
|
||||
def test_list_transformer(self):
|
||||
query_string = 'coord=1.4,13,15.1&limit=100'
|
||||
query_string = 'coord=1.4,13,15.1&limit=100&things=4,,1'
|
||||
self.simulate_request('/', query_string=query_string)
|
||||
|
||||
req = self.resource.req
|
||||
@@ -206,15 +223,13 @@ class TestQueryParams(testing.TestBase):
|
||||
actual = req.get_param_as_list('coord', transform=float)
|
||||
self.assertEquals(actual, expected)
|
||||
|
||||
expected = ['4', None, '1']
|
||||
actual = req.get_param_as_list('things', transform=str)
|
||||
self.assertEquals(actual, expected)
|
||||
|
||||
expected = [4, None, 1]
|
||||
actual = req.get_param_as_list('things', transform=int)
|
||||
self.assertEquals(actual, expected)
|
||||
|
||||
self.assertRaises(falcon.HTTPBadRequest,
|
||||
req.get_param_as_list, 'coord', transform=int)
|
||||
|
||||
def test_bogus_input(self):
|
||||
query_string = 'colors=red,green,&limit=1&pickle'
|
||||
self.simulate_request('/', query_string=query_string)
|
||||
|
||||
req = self.resource.req
|
||||
self.assertEquals(req.get_param_as_list('colors'),
|
||||
['red', 'green', ''])
|
||||
self.assertEquals(req.get_param('limit'), '1')
|
||||
self.assertIs(req.get_param('pickle'), None)
|
||||
|
||||
Reference in New Issue
Block a user