1cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum"""Manage shelves of pickled objects. 2cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 3cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van RossumA "shelf" is a persistent, dictionary-like object. The difference 4cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossumwith dbm databases is that the values (not the keys!) in a shelf can 5cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossumbe essentially arbitrary Python objects -- anything that the "pickle" 6cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossummodule can handle. This includes most class instances, recursive data 7cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossumtypes, and objects containing lots of shared sub-objects. The keys 8cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossumare ordinary strings. 9cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 10cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van RossumTo summarize the interface (key is a string, data is an arbitrary 11cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossumobject): 12cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 1313a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake import shelve 1413a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake d = shelve.open(filename) # open, with (g)dbm filename -- no suffix 15cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 1613a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake d[key] = data # store data at key (overwrites old data if 1713a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake # using an existing key) 180eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters data = d[key] # retrieve a COPY of the data at key (raise 19153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis # KeyError if no such key) -- NOTE that this 20153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis # access returns a *copy* of the entry! 2113a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake del d[key] # delete data stored at key (raises KeyError 2213a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake # if no such key) 23e2b70bcf7401477936fba99a8bf4a1f759ecc8a3Guido van Rossum flag = key in d # true if the key exists 2413a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake list = d.keys() # a list of all existing keys (slow!) 25cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 2613a2c279c504ae58c20baba5f0b3d1d6c0a85ed3Fred Drake d.close() # close it 27cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 28cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van RossumDependent on the implementation, closing a persistent dictionary may 29cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossumor may not be necessary to flush changes to disk. 30153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis 31153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. LöwisNormally, d[key] returns a COPY of the entry. This needs care when 32153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwismutable entries are mutated: for example, if d[key] is a list, 33153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis d[key].append(anitem) 34153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisdoes NOT modify the entry d[key] itself, as stored in the persistent 35153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwismapping -- it only modifies the copy, which is then immediately 36153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisdiscarded, so that the append has NO effect whatsoever. To append an 37153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisitem to d[key] in a way that will affect the persistent mapping, use: 38153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis data = d[key] 39153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis data.append(anitem) 40153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis d[key] = data 41153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis 42153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. LöwisTo avoid the problem with mutable entries, you may pass the keyword 43153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisargument writeback=True in the call to shelve.open. When you use: 44153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis d = shelve.open(filename, writeback=True) 45153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisthen d keeps a cache of all entries you access, and writes them all back 46153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisto the persistent mapping when you call d.close(). This ensures that 47153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwissuch usage as d[key].append(anitem) works as intended. 48153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis 49153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. LöwisHowever, using keyword argument writeback=True may consume vast amount 50153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisof memory for the cache, and it may make d.close() very slow, if you 51153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisaccess many of d's entries after opening it in this way: d has no way to 52153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwischeck which of the entries you access are mutable and/or which ones you 53153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisactually mutate, so it must cache, and write back at close, all of the 54153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisentries that you access. You can call d.sync() to write back all the 55153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisentries in the cache, and empty the cache (d.sync() also synchronizes 56153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwisthe persistent dictionary on disk, if feasible). 57cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum""" 58a48061a5804418a63aac24bfce444fd555e3ffe7Guido van Rossum 5968937b4cbcc3e88d4207e6391a311f9b7d067b71Guido van Rossumfrom pickle import Pickler, Unpickler 60d24fffe7c67c2097aa33e04498dc6b3ae0cc17abBrett Cannonfrom io import BytesIO 61a48061a5804418a63aac24bfce444fd555e3ffe7Guido van Rossum 62b9da9bc0a04b718e8395e2e88c3053ab944579b7Raymond Hettingerimport collections 637994716b6bcaeca64f47b7b3ed4e411bb6afc415Raymond Hettinger 64ac0f965fd0d33da64f42d1a7ece1a66c80c3ff52Andrew Svetlov__all__ = ["Shelf", "BsdDbShelf", "DbfilenameShelf", "open"] 65cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 66d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Petersonclass _ClosedDict(collections.MutableMapping): 67d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson 'Marker for a closed dict. Access attempts raise a ValueError.' 68d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson 69d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson def closed(self, *args): 70d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson raise ValueError('invalid operation on closed shelf') 71d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson __iter__ = __len__ = __getitem__ = __setitem__ = __delitem__ = keys = closed 72d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson 73d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson def __repr__(self): 74d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson return '<Closed Dictionary>' 75d63137159b0e0cdbaec5d4cb98b3de5940173ee3Benjamin Peterson 76732324a3f86a352217b01ae2438b6db7691ae0b1Georg Brandl 77b9da9bc0a04b718e8395e2e88c3053ab944579b7Raymond Hettingerclass Shelf(collections.MutableMapping): 78495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters """Base class for shelf implementations. 79495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 80495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters This is initialized with a dictionary-like object. 81495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters See the module's __doc__ string for an overview of the interface. 82495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters """ 83495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 8479c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis def __init__(self, dict, protocol=None, writeback=False, 8579c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis keyencoding="utf-8"): 86495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters self.dict = dict 87153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis if protocol is None: 8885602268dc9d57b8965b619dd313868ebe4b9b8fRaymond Hettinger protocol = 3 89153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self._protocol = protocol 90153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self.writeback = writeback 91153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self.cache = {} 92732324a3f86a352217b01ae2438b6db7691ae0b1Georg Brandl self.keyencoding = keyencoding 93495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 94b9da9bc0a04b718e8395e2e88c3053ab944579b7Raymond Hettinger def __iter__(self): 9579c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis for k in self.dict.keys(): 9679c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis yield k.decode(self.keyencoding) 97495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 98495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def __len__(self): 99495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters return len(self.dict) 100495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 101e4913c9987d88f5a1bd52753afe8eb6bee32f6e9Martin v. Löwis def __contains__(self, key): 10279c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis return key.encode(self.keyencoding) in self.dict 103e4913c9987d88f5a1bd52753afe8eb6bee32f6e9Martin v. Löwis 104495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def get(self, key, default=None): 10579c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis if key.encode(self.keyencoding) in self.dict: 106495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters return self[key] 107495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters return default 108495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 109495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def __getitem__(self, key): 110153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis try: 111153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis value = self.cache[key] 112153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis except KeyError: 11379c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis f = BytesIO(self.dict[key.encode(self.keyencoding)]) 114153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis value = Unpickler(f).load() 115153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis if self.writeback: 116153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self.cache[key] = value 117153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis return value 118495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 119495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def __setitem__(self, key, value): 120153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis if self.writeback: 121153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self.cache[key] = value 122d24fffe7c67c2097aa33e04498dc6b3ae0cc17abBrett Cannon f = BytesIO() 123153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis p = Pickler(f, self._protocol) 124495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters p.dump(value) 12579c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis self.dict[key.encode(self.keyencoding)] = f.getvalue() 126495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 127495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def __delitem__(self, key): 12879c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis del self.dict[key.encode(self.keyencoding)] 129153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis try: 130153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis del self.cache[key] 131153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis except KeyError: 132153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis pass 133495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 134ef08fb1f040cb51e752c6b1322008714262fbf3eAndrew Svetlov def __enter__(self): 135ef08fb1f040cb51e752c6b1322008714262fbf3eAndrew Svetlov return self 136ef08fb1f040cb51e752c6b1322008714262fbf3eAndrew Svetlov 137ef08fb1f040cb51e752c6b1322008714262fbf3eAndrew Svetlov def __exit__(self, type, value, traceback): 138ef08fb1f040cb51e752c6b1322008714262fbf3eAndrew Svetlov self.close() 139ef08fb1f040cb51e752c6b1322008714262fbf3eAndrew Svetlov 140495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def close(self): 1417e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka if self.dict is None: 1427e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka return 143495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters try: 1447e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka self.sync() 1457e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka try: 1467e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka self.dict.close() 1477e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka except AttributeError: 1487e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka pass 1497e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka finally: 1507e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka # Catch errors that may happen when close is called from __del__ 1517e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka # because CPython is in interpreter shutdown. 1527e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka try: 1537e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka self.dict = _ClosedDict() 1547e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka except: 1557e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka self.dict = None 156495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 157495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def __del__(self): 1580e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters if not hasattr(self, 'writeback'): 1590e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters # __init__ didn't succeed, so don't bother closing 160ef08fb1f040cb51e752c6b1322008714262fbf3eAndrew Svetlov # see http://bugs.python.org/issue1339007 for details 1610e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters return 162495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters self.close() 163495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 164495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def sync(self): 165153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis if self.writeback and self.cache: 166153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self.writeback = False 167cc2b0161257495f859200bce0aea3ed7e646feb3Guido van Rossum for key, entry in self.cache.items(): 168153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self[key] = entry 169153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self.writeback = True 170153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis self.cache = {} 171495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters if hasattr(self.dict, 'sync'): 172495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters self.dict.sync() 173495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 174cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 175abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossumclass BsdDbShelf(Shelf): 176495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters """Shelf implementation using the "BSD" db interface. 177abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 178495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters This adds methods first(), next(), previous(), last() and 179495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters set_location() that have no counterpart in [g]dbm databases. 180abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 181495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters The actual database must be opened using one of the "bsddb" 182495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or 183495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters bsddb.rnopen) and passed to the constructor. 184abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 185495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters See the module's __doc__ string for an overview of the interface. 186495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters """ 187abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 18879c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis def __init__(self, dict, protocol=None, writeback=False, 18979c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis keyencoding="utf-8"): 19079c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis Shelf.__init__(self, dict, protocol, writeback, keyencoding) 191abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 192495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def set_location(self, key): 193495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters (key, value) = self.dict.set_location(key) 194d24fffe7c67c2097aa33e04498dc6b3ae0cc17abBrett Cannon f = BytesIO(value) 19579c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis return (key.decode(self.keyencoding), Unpickler(f).load()) 196abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 197495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def next(self): 198a18af4e7a2091d11478754eb66ae387a85535763Georg Brandl (key, value) = next(self.dict) 199d24fffe7c67c2097aa33e04498dc6b3ae0cc17abBrett Cannon f = BytesIO(value) 20079c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis return (key.decode(self.keyencoding), Unpickler(f).load()) 201abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 202495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def previous(self): 203495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters (key, value) = self.dict.previous() 204d24fffe7c67c2097aa33e04498dc6b3ae0cc17abBrett Cannon f = BytesIO(value) 20579c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis return (key.decode(self.keyencoding), Unpickler(f).load()) 206abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 207495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def first(self): 208495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters (key, value) = self.dict.first() 209d24fffe7c67c2097aa33e04498dc6b3ae0cc17abBrett Cannon f = BytesIO(value) 21079c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis return (key.decode(self.keyencoding), Unpickler(f).load()) 211abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 212495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters def last(self): 213495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters (key, value) = self.dict.last() 214d24fffe7c67c2097aa33e04498dc6b3ae0cc17abBrett Cannon f = BytesIO(value) 21579c320898d43eaafa28c1c67a105a17cb9b233bfMartin v. Löwis return (key.decode(self.keyencoding), Unpickler(f).load()) 216abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 217abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossum 218abad1cc647a9c8e892829f8066dc85ad3b7c9632Guido van Rossumclass DbfilenameShelf(Shelf): 2190a7ac7d70d370544c6a9d118bbbd6886ad4f5ce5Georg Brandl """Shelf implementation using the "dbm" generic dbm interface. 220495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 221495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters This is initialized with the filename for the dbm database. 222495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters See the module's __doc__ string for an overview of the interface. 223495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters """ 224cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 2251bc82f891c2ed0c4b062158d2c8339fb90406395Raymond Hettinger def __init__(self, filename, flag='c', protocol=None, writeback=False): 2260a7ac7d70d370544c6a9d118bbbd6886ad4f5ce5Georg Brandl import dbm 2270a7ac7d70d370544c6a9d118bbbd6886ad4f5ce5Georg Brandl Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback) 228a48061a5804418a63aac24bfce444fd555e3ffe7Guido van Rossum 229cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 2301bc82f891c2ed0c4b062158d2c8339fb90406395Raymond Hettingerdef open(filename, flag='c', protocol=None, writeback=False): 231495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters """Open a persistent dictionary for reading and writing. 232495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters 233153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis The filename parameter is the base filename for the underlying 234153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis database. As a side-effect, an extension may be added to the 235153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis filename and more than one file may be created. The optional flag 236153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis parameter has the same interpretation as the flag parameter of 2370a7ac7d70d370544c6a9d118bbbd6886ad4f5ce5Georg Brandl dbm.open(). The optional protocol parameter specifies the 238153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis version of the pickle protocol (0, 1, or 2). 239153c9e493e9850340fd686ab7a6e5c176953abd7Martin v. Löwis 240495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters See the module's __doc__ string for an overview of the interface. 241495ad3c8ccb9ed3554177a3e8687676c78e667deTim Peters """ 242cc6764c1ba92e947638d1c0c8fe8d312a0e3e6d4Guido van Rossum 2431bc82f891c2ed0c4b062158d2c8339fb90406395Raymond Hettinger return DbfilenameShelf(filename, flag, protocol, writeback) 244