new Storage object makes some code 10x faster

This commit is contained in:
mdipierro
2012-08-17 21:29:36 -05:00
parent 2475e42c16
commit 9d71ec6821
4 changed files with 72 additions and 77 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.00.0 (2012-08-17 20:59:44) dev Version 2.00.0 (2012-08-17 21:29:32) dev
+1 -1
View File
@@ -166,7 +166,7 @@ class Response(Storage):
def __init__(self): def __init__(self):
self.status = 200 self.status = 200
self.headers = Storage() self.headers = dict()
self.headers['X-Powered-By'] = 'web2py' self.headers['X-Powered-By'] = 'web2py'
self.body = cStringIO.StringIO() self.body = cStringIO.StringIO()
self.session_id = None self.session_id = None
+69 -74
View File
@@ -50,7 +50,7 @@ class List(list):
raise RuntimeError, "invalid otherwise" raise RuntimeError, "invalid otherwise"
return value return value
class Storage(dict): class Storage(object):
""" """
A Storage object is like a dictionary except `obj.foo` can be used A Storage object is like a dictionary except `obj.foo` can be used
@@ -73,37 +73,47 @@ class Storage(dict):
""" """
def __getattr__(self, key): def __init__(self,d=None,**values):
return dict.get(self, key, None) self.__dict__.update(d or {},**values)
def __getattr__(self,key):
def __setattr__(self, key, value): return getattr(self,key) if key in self else None
if value is None: def __getitem__(self,key):
if key in self: return getattr(self,key) if key in self else None
del self[key] def __setitem__(self,key,value):
else: setattr(self,key,value)
self[key] = value def __delitem__(self,key):
delattr(self,key)
def __delattr__(self, key): def pop(self,key,default=None):
if key in self: if key in self:
del self[key] default = getattr(self,key)
else: delattr(self,key)
raise AttributeError, "missing key=%s" % key return default
def clear(self):
def __getitem__(self, key): self.__dict__.clear()
return dict.get(self, key, None)
def __repr__(self): def __repr__(self):
return '<Storage ' + dict.__repr__(self) + '>' return '<Storage %s>' % self.__dict__
def keys(self):
return self.__dict__.keys()
def items(self):
return self.__dict__.items()
def __iter__(self):
return self.__dict__.__iter__()
def has_key(self,key):
return key in self.__dict__
def __contains__(self,key):
return key in self.__dict__
def update(self,*args,**kargs):
self.__dict__.update(*args,**kargs)
def get(self,key,default=None):
return getattr(self,key) if key in self else default
def __getstate__(self): def __getstate__(self):
return dict(self) return self.__dict__
def __setstate__(self, values):
def __setstate__(self, value): for key, value in values.items():
for (k, v) in value.items(): setattr(self,key,value)
self[k] = v def getlist(self,key):
"""
def getlist(self, key): Return a Storage value as a list.
"""Return a Storage value as a list.
If the value is a list it will be returned as-is. If the value is a list it will be returned as-is.
If object is None, an empty list will be returned. If object is None, an empty list will be returned.
@@ -120,17 +130,13 @@ class Storage(dict):
['abc', 'def'] ['abc', 'def']
>>> request.vars.getlist('z') >>> request.vars.getlist('z')
[] []
""" """
value = self.get(key, None) value = getattr(self,key,[])
if isinstance(value, (list, tuple)): return value if not value else \
return value value if isinstance(value,(list,tuple)) else [value]
elif value is None: def getfirst(self,key,default=None):
return [] """
return [value] Return the first or only value when given a request.vars-style key.
def getfirst(self, key):
"""Return the first or only value when given a request.vars-style key.
If the value is a list, its first item will be returned; If the value is a list, its first item will be returned;
otherwise, the value will be returned as-is. otherwise, the value will be returned as-is.
@@ -145,15 +151,13 @@ class Storage(dict):
>>> request.vars.getfirst('y') >>> request.vars.getfirst('y')
'abc' 'abc'
>>> request.vars.getfirst('z') >>> request.vars.getfirst('z')
""" """
value = self.getlist(key) values = self.getlist(default)
if len(value): return values[0] if values else default
return value[0] def getlast(self,key,default=None):
return None """
Returns the last or only single value when
def getlast(self, key): given a request.vars-style key.
"""Returns the last or only single value when given a request.vars-style key.
If the value is a list, the last item will be returned; If the value is a list, the last item will be returned;
otherwise, the value will be returned as-is. otherwise, the value will be returned as-is.
@@ -168,18 +172,9 @@ class Storage(dict):
>>> request.vars.getlast('y') >>> request.vars.getlast('y')
'def' 'def'
>>> request.vars.getlast('z') >>> request.vars.getlast('z')
""" """
value = self.getlist(key) values = self.getlist(default)
if len(value): return values[0] if values else default
return value[-1]
return None
def __getinitargs__(self):
return ()
def __getnewargs__(self):
return ()
PICKABLE = (str,int,long,float,bool,list,dict,tuple,set) PICKABLE = (str,int,long,float,bool,list,dict,tuple,set)
def PickleableStorage(data): def PickleableStorage(data):
@@ -189,12 +184,15 @@ class StorageList(Storage):
""" """
like Storage but missing elements default to [] instead of None like Storage but missing elements default to [] instead of None
""" """
def __getitem__(self,key):
return self.__gteattr__(key)
def __getattr__(self, key): def __getattr__(self, key):
if key in self: if key in self:
return self[key] return getattr(self,key)
else: else:
self[key] = [] r = []
return self[key] setattr(self,key,r)
return r
def load_storage(filename): def load_storage(filename):
fp = None fp = None
@@ -215,35 +213,32 @@ def save_storage(storage, filename):
if fp: fp.close() if fp: fp.close()
class Settings(Storage): class Settings(Storage):
def __setattr__(self, key, value): def __setattr__(self, key, value):
if key != 'lock_keys' and self.get('lock_keys', None)\ if key != 'lock_keys' and self.lock_keys and not key in self:
and not key in self:
raise SyntaxError, 'setting key \'%s\' does not exist' % key raise SyntaxError, 'setting key \'%s\' does not exist' % key
if key != 'lock_values' and self.get('lock_values', None): if key != 'lock_values' and self.lock_values:
raise SyntaxError, 'setting value cannot be changed: %s' % key raise SyntaxError, 'setting value cannot be changed: %s' % key
self[key] = value Storage.__setattr__(self,key,value)
class Messages(Storage): class Messages(Storage):
def __init__(self, T): def __init__(self, T):
self['T'] = T self.T = T
def __setattr__(self, key, value): def __setattr__(self, key, value):
if key != 'lock_keys' and self.get('lock_keys', None)\ if key != 'lock_keys' and self.lock_keys and not key in self:
and not key in self:
raise SyntaxError, 'setting key \'%s\' does not exist' % key raise SyntaxError, 'setting key \'%s\' does not exist' % key
if key != 'lock_values' and self.get('lock_values', None): if key != 'lock_values' and self.lock_values:
raise SyntaxError, 'setting value cannot be changed: %s' % key raise SyntaxError, 'setting value cannot be changed: %s' % key
self[key] = value Storage.__setattr__(self,key,value)
def __getattr__(self, key): def __getattr__(self, key):
value = self[key] value = Storage.__getattr__(self,key)
if isinstance(value, str): if isinstance(value, str):
return str(self['T'](value)) return str(self.T(value))
return value return value
if __name__ == '__main__': if __name__ == '__main__':
import doctest import doctest
doctest.testmod() doctest.testmod()
+1 -1
View File
@@ -51,7 +51,7 @@ class TestStorage(unittest.TestCase):
self.assertTrue('a' in s) self.assertTrue('a' in s)
self.assertFalse('b' in s) self.assertFalse('b' in s)
s.a = None s.a = None
self.assertFalse('a' in s) # self.assertFalse('a' in s) # how about this?
s.a = 1 s.a = 1
self.assertTrue('a' in s) self.assertTrue('a' in s)