diff --git a/gluon/storage.py b/gluon/storage.py index 6996d805..3b0780fd 100644 --- a/gluon/storage.py +++ b/gluon/storage.py @@ -269,53 +269,51 @@ class FastStorage(dict): class List(list): + """ Like a regular python list but a[i] if i is out of bounds returns None - instead of `IndexOutOfBounds` + instead of `IndexOutOfBounds`. """ - def __call__(self, i, default=DEFAULT, cast=None, otherwise=None): + def __call__(self, i, default=None, cast=None, otherwise=None): """Allows to use a special syntax for fast-check of `request.args()` validity - Args: i: index default: use this value if arg not found cast: type cast otherwise: can be: - - None: results in a 404 - str: redirect to this address - callable: calls the function (nothing is passed) - Example: You can use:: - request.args(0,default=0,cast=int,otherwise='http://error_url') request.args(0,default=0,cast=int,otherwise=lambda:...) - """ + value = self[i] or default + try: + if cast: + value = cast(value) + if not value and otherwise: + raise ValueError('Otherwise will raised.') + except (ValueError, TypeError): + from http import HTTP, redirect + if otherwise is None: + raise HTTP(404) + elif isinstance(otherwise, str): + redirect(otherwise) + elif callable(otherwise): + return otherwise() + else: + raise RuntimeError("invalid otherwise") + return value + + def __getitem__(self, i): n = len(self) if 0 <= i < n or -n <= i < 0: - value = self[i] - elif default is DEFAULT: - value = None - else: - value, cast = default, False - if cast: - try: - value = cast(value) - except (ValueError, TypeError): - from http import HTTP, redirect - if otherwise is None: - raise HTTP(404) - elif isinstance(otherwise, str): - redirect(otherwise) - elif callable(otherwise): - return otherwise() - else: - raise RuntimeError("invalid otherwise") - return value + return super(List, self).__getitem__(i) + return None if __name__ == '__main__': diff --git a/gluon/tests/test_storage.py b/gluon/tests/test_storage.py index e046506b..804a3fb8 100644 --- a/gluon/tests/test_storage.py +++ b/gluon/tests/test_storage.py @@ -125,8 +125,12 @@ class TestList(unittest.TestCase): def test_listcall(self): a = List((1, 2, 3)) self.assertEqual(a(1), 2) + self.assertEqual(a[1], 2) + self.assertEqual(a(3), None) + self.assertEqual(a[3], None) self.assertEqual(a(-1), 3) self.assertEqual(a(-5), None) + self.assertEqual(a[-5], None) self.assertEqual(a(-5, default='x'), 'x') self.assertEqual(a(-3, cast=str), '1') a.append('1234')