diff --git a/applications/welcome/routes.example.py b/applications/welcome/routes.example.py index 95130e18..7a3e73d1 100644 --- a/applications/welcome/routes.example.py +++ b/applications/welcome/routes.example.py @@ -7,11 +7,11 @@ # Language from default.py or 'en' (if the file is not found) is used as # a default_language # -# See /router.example.py for parameter's detail +# See /examples/routes.parametric.example.py for parameter's detail #------------------------------------------------------------------------------------- # To enable this route file you must do the steps: # -# 1. rename /router.example.py to routes.py +# 1. rename /examples/routes.parametric.example.py to routes.py # 2. rename this APP/routes.example.py to APP/routes.py # (where APP - is your application directory) # 3. restart web2py (or reload routes in web2py admin interfase) 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_cache.py b/gluon/tests/test_cache.py index 1522c6f0..68dd743e 100644 --- a/gluon/tests/test_cache.py +++ b/gluon/tests/test_cache.py @@ -13,6 +13,7 @@ fix_sys_path(__file__) from storage import Storage from cache import CacheInRam, CacheOnDisk, Cache +from gluon.dal import DAL, Field oldcwd = None @@ -30,6 +31,11 @@ def tearDownModule(): if oldcwd: os.chdir(oldcwd) oldcwd = None + try: + os.unlink('dummy.db') + except: + pass + class TestCache(unittest.TestCase): @@ -107,7 +113,34 @@ class TestCache(unittest.TestCase): cache.clear(regex=r'a*') self.assertEqual(cache('a1', lambda: 2, 0), 2) self.assertEqual(cache('a2', lambda: 3, 100), 3) - return + + def testDALcache(self): + s = Storage({'application': 'admin', + 'folder': 'applications/admin'}) + cache = Cache(s) + db = DAL(check_reserved=['all']) + db.define_table('t_a', Field('f_a')) + db.t_a.insert(f_a='test') + db.commit() + a = db(db.t_a.id > 0).select(cache=(cache.ram, 60), cacheable=True) + b = db(db.t_a.id > 0).select(cache=(cache.ram, 60), cacheable=True) + self.assertEqual(a.as_csv(), b.as_csv()) + c = db(db.t_a.id > 0).select(cache=(cache.disk, 60), cacheable=True) + d = db(db.t_a.id > 0).select(cache=(cache.disk, 60), cacheable=True) + self.assertEqual(c.as_csv(), d.as_csv()) + self.assertEqual(a.as_csv(), c.as_csv()) + self.assertEqual(b.as_csv(), d.as_csv()) + e = db(db.t_a.id > 0).select(cache=(cache.disk, 60)) + f = db(db.t_a.id > 0).select(cache=(cache.disk, 60)) + self.assertEqual(e.as_csv(), f.as_csv()) + self.assertEqual(a.as_csv(), f.as_csv()) + g = db(db.t_a.id > 0).select(cache=(cache.ram, 60)) + h = db(db.t_a.id > 0).select(cache=(cache.ram, 60)) + self.assertEqual(g.as_csv(), h.as_csv()) + self.assertEqual(a.as_csv(), h.as_csv()) + db.t_a.drop() + db.close() + if __name__ == '__main__': setUpModule() # pre-python-2.7 diff --git a/gluon/tests/test_dal.py b/gluon/tests/test_dal.py index 35c9c9b9..472750a9 100644 --- a/gluon/tests/test_dal.py +++ b/gluon/tests/test_dal.py @@ -4,6 +4,7 @@ Unit tests for gluon.dal """ +import os import unittest from fix_path import fix_sys_path @@ -12,8 +13,15 @@ fix_sys_path(__file__) from gluon.dal import DAL, Field +def tearDownModule(): + try: + os.unlink('dummy.db') + except: + pass + class TestDALSubclass(unittest.TestCase): + def testRun(self): from gluon.serializers import custom_json, xml from gluon import sqlhtml @@ -22,19 +30,26 @@ class TestDALSubclass(unittest.TestCase): self.assertEqual(db.serializers['xml'], xml) self.assertEqual(db.representers['rows_render'], sqlhtml.represent) self.assertEqual(db.representers['rows_xml'], sqlhtml.SQLTABLE) + db.close() def testSerialization(self): import pickle db = DAL(check_reserved=['all']) db.define_table('t_a', Field('f_a')) db.t_a.insert(f_a='test') - a = db(db.t_a.id>0).select(cacheable=True) + a = db(db.t_a.id > 0).select(cacheable=True) s = pickle.dumps(a) b = pickle.loads(s) self.assertEqual(a.db, b.db) + db.t_a.drop() + db.close() """ TODO: class TestDefaultValidators(unittest.TestCase): def testRun(self): pass """ + +if __name__ == '__main__': + unittest.main() + tearDownModule() 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') diff --git a/scripts/web2py.ubuntu.sh b/scripts/web2py.ubuntu.sh index d3dc19ea..e6b2662b 100755 --- a/scripts/web2py.ubuntu.sh +++ b/scripts/web2py.ubuntu.sh @@ -62,7 +62,7 @@ do_start() start-stop-daemon --stop --test --quiet --pidfile $PIDFILE \ && return 1 - start-stop-daemon --start --quiet --pidfile $PIDFILE \ + start-stop-daemon --start --quiet -m --pidfile $PIDFILE \ ${DAEMON_USER:+--chuid $DAEMON_USER} --chdir $DAEMON_DIR \ --background --exec $DAEMON -- $DAEMON_ARGS \ || return 2