*** Python-2.2.1/Lib/shelve.py Tue May 7 10:03:58 2002 --- patched/shelve.py Tue May 7 10:04:34 2002 *************** *** 26,31 **** --- 26,43 ---- Dependent on the implementation, closing a persistent dictionary may or may not be necessary to flush changes to disk. + + If optional flag smart=1 is passed in the .open call, the resulting + object 'd' keeps an in-memory 'cache' of all data retrieved from it + or stored to it since it was opened. Apart from speed issues, which + may cut either way, this ensures that a modifiable item may indeed + be modified *and have the modifications KNOWN to the shelf object it + comes from*. WITHOUT smart=1: + d['spam'] = [1,2,3] # ok + d['spam'].append(4) # doesn't "take"! + the value at d['spam'] remains [1,2,3]: the .append modification is + done on a temporary object, NOT on the actual stored value! WITH + smart=1, this behaves in a less surprising way. """ # Try using cPickle and cStringIO if available. *************** *** 49,56 **** See the module's __doc__ string for an overview of the interface. """ ! def __init__(self, dict): self.dict = dict def keys(self): return self.dict.keys() --- 61,70 ---- See the module's __doc__ string for an overview of the interface. """ ! def __init__(self, dict, smart=0): self.dict = dict + if smart: + self.cache = {} def keys(self): return self.dict.keys() *************** *** 67,85 **** return default def __getitem__(self, key): f = StringIO(self.dict[key]) ! return Unpickler(f).load() def __setitem__(self, key, value): f = StringIO() p = Pickler(f) p.dump(value) ! self.dict[key] = f.getvalue() def __delitem__(self, key): del self.dict[key] def close(self): try: self.dict.close() except: --- 81,110 ---- return default def __getitem__(self, key): + try: return self.cache[key] + except: pass f = StringIO(self.dict[key]) ! result = Unpickler(f).load() ! try: self.cache[key] = result ! except: pass ! return result def __setitem__(self, key, value): f = StringIO() p = Pickler(f) p.dump(value) ! result = f.getvalue() ! self.dict[key] = result ! try: self.cache[key] = result ! except: pass def __delitem__(self, key): del self.dict[key] + try: del self.cache[key] + except: pass def close(self): + self.sync() try: self.dict.close() except: *************** *** 90,95 **** --- 115,127 ---- self.close() def sync(self): + try: c=self.cache + except: pass + else: + del self.cache + for k in c: + self[k] = c[k] + self.cache = {} if hasattr(self.dict, 'sync'): self.dict.sync() *************** *** 107,114 **** See the module's __doc__ string for an overview of the interface. """ ! def __init__(self, dict): ! Shelf.__init__(self, dict) def set_location(self, key): (key, value) = self.dict.set_location(key) --- 139,146 ---- See the module's __doc__ string for an overview of the interface. """ ! def __init__(self, dict, smart=0): ! Shelf.__init__(self, dict, smart) def set_location(self, key): (key, value) = self.dict.set_location(key) *************** *** 143,158 **** See the module's __doc__ string for an overview of the interface. """ ! def __init__(self, filename, flag='c'): import anydbm ! Shelf.__init__(self, anydbm.open(filename, flag)) ! def open(filename, flag='c'): """Open a persistent dictionary for reading and writing. Argument is the filename for the dbm database. See the module's __doc__ string for an overview of the interface. """ ! return DbfilenameShelf(filename, flag) --- 175,190 ---- See the module's __doc__ string for an overview of the interface. """ ! def __init__(self, filename, flag='c', smart=0): import anydbm ! Shelf.__init__(self, anydbm.open(filename, flag), smart) ! def open(filename, flag='c', smart=0): """Open a persistent dictionary for reading and writing. Argument is the filename for the dbm database. See the module's __doc__ string for an overview of the interface. """ ! return DbfilenameShelf(filename, flag, smart)