Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ShExBy/shex_roo.../usr/lib64/python3....
File: shelve.py
"""Manage shelves of pickled objects.
[0] Fix | Delete
[1] Fix | Delete
A "shelf" is a persistent, dictionary-like object. The difference
[2] Fix | Delete
with dbm databases is that the values (not the keys!) in a shelf can
[3] Fix | Delete
be essentially arbitrary Python objects -- anything that the "pickle"
[4] Fix | Delete
module can handle. This includes most class instances, recursive data
[5] Fix | Delete
types, and objects containing lots of shared sub-objects. The keys
[6] Fix | Delete
are ordinary strings.
[7] Fix | Delete
[8] Fix | Delete
To summarize the interface (key is a string, data is an arbitrary
[9] Fix | Delete
object):
[10] Fix | Delete
[11] Fix | Delete
import shelve
[12] Fix | Delete
d = shelve.open(filename) # open, with (g)dbm filename -- no suffix
[13] Fix | Delete
[14] Fix | Delete
d[key] = data # store data at key (overwrites old data if
[15] Fix | Delete
# using an existing key)
[16] Fix | Delete
data = d[key] # retrieve a COPY of the data at key (raise
[17] Fix | Delete
# KeyError if no such key) -- NOTE that this
[18] Fix | Delete
# access returns a *copy* of the entry!
[19] Fix | Delete
del d[key] # delete data stored at key (raises KeyError
[20] Fix | Delete
# if no such key)
[21] Fix | Delete
flag = key in d # true if the key exists
[22] Fix | Delete
list = d.keys() # a list of all existing keys (slow!)
[23] Fix | Delete
[24] Fix | Delete
d.close() # close it
[25] Fix | Delete
[26] Fix | Delete
Dependent on the implementation, closing a persistent dictionary may
[27] Fix | Delete
or may not be necessary to flush changes to disk.
[28] Fix | Delete
[29] Fix | Delete
Normally, d[key] returns a COPY of the entry. This needs care when
[30] Fix | Delete
mutable entries are mutated: for example, if d[key] is a list,
[31] Fix | Delete
d[key].append(anitem)
[32] Fix | Delete
does NOT modify the entry d[key] itself, as stored in the persistent
[33] Fix | Delete
mapping -- it only modifies the copy, which is then immediately
[34] Fix | Delete
discarded, so that the append has NO effect whatsoever. To append an
[35] Fix | Delete
item to d[key] in a way that will affect the persistent mapping, use:
[36] Fix | Delete
data = d[key]
[37] Fix | Delete
data.append(anitem)
[38] Fix | Delete
d[key] = data
[39] Fix | Delete
[40] Fix | Delete
To avoid the problem with mutable entries, you may pass the keyword
[41] Fix | Delete
argument writeback=True in the call to shelve.open. When you use:
[42] Fix | Delete
d = shelve.open(filename, writeback=True)
[43] Fix | Delete
then d keeps a cache of all entries you access, and writes them all back
[44] Fix | Delete
to the persistent mapping when you call d.close(). This ensures that
[45] Fix | Delete
such usage as d[key].append(anitem) works as intended.
[46] Fix | Delete
[47] Fix | Delete
However, using keyword argument writeback=True may consume vast amount
[48] Fix | Delete
of memory for the cache, and it may make d.close() very slow, if you
[49] Fix | Delete
access many of d's entries after opening it in this way: d has no way to
[50] Fix | Delete
check which of the entries you access are mutable and/or which ones you
[51] Fix | Delete
actually mutate, so it must cache, and write back at close, all of the
[52] Fix | Delete
entries that you access. You can call d.sync() to write back all the
[53] Fix | Delete
entries in the cache, and empty the cache (d.sync() also synchronizes
[54] Fix | Delete
the persistent dictionary on disk, if feasible).
[55] Fix | Delete
"""
[56] Fix | Delete
[57] Fix | Delete
from pickle import Pickler, Unpickler
[58] Fix | Delete
from io import BytesIO
[59] Fix | Delete
[60] Fix | Delete
import collections
[61] Fix | Delete
[62] Fix | Delete
__all__ = ["Shelf", "BsdDbShelf", "DbfilenameShelf", "open"]
[63] Fix | Delete
[64] Fix | Delete
class _ClosedDict(collections.MutableMapping):
[65] Fix | Delete
'Marker for a closed dict. Access attempts raise a ValueError.'
[66] Fix | Delete
[67] Fix | Delete
def closed(self, *args):
[68] Fix | Delete
raise ValueError('invalid operation on closed shelf')
[69] Fix | Delete
__iter__ = __len__ = __getitem__ = __setitem__ = __delitem__ = keys = closed
[70] Fix | Delete
[71] Fix | Delete
def __repr__(self):
[72] Fix | Delete
return '<Closed Dictionary>'
[73] Fix | Delete
[74] Fix | Delete
[75] Fix | Delete
class Shelf(collections.MutableMapping):
[76] Fix | Delete
"""Base class for shelf implementations.
[77] Fix | Delete
[78] Fix | Delete
This is initialized with a dictionary-like object.
[79] Fix | Delete
See the module's __doc__ string for an overview of the interface.
[80] Fix | Delete
"""
[81] Fix | Delete
[82] Fix | Delete
def __init__(self, dict, protocol=None, writeback=False,
[83] Fix | Delete
keyencoding="utf-8"):
[84] Fix | Delete
self.dict = dict
[85] Fix | Delete
if protocol is None:
[86] Fix | Delete
protocol = 3
[87] Fix | Delete
self._protocol = protocol
[88] Fix | Delete
self.writeback = writeback
[89] Fix | Delete
self.cache = {}
[90] Fix | Delete
self.keyencoding = keyencoding
[91] Fix | Delete
[92] Fix | Delete
def __iter__(self):
[93] Fix | Delete
for k in self.dict.keys():
[94] Fix | Delete
yield k.decode(self.keyencoding)
[95] Fix | Delete
[96] Fix | Delete
def __len__(self):
[97] Fix | Delete
return len(self.dict)
[98] Fix | Delete
[99] Fix | Delete
def __contains__(self, key):
[100] Fix | Delete
return key.encode(self.keyencoding) in self.dict
[101] Fix | Delete
[102] Fix | Delete
def get(self, key, default=None):
[103] Fix | Delete
if key.encode(self.keyencoding) in self.dict:
[104] Fix | Delete
return self[key]
[105] Fix | Delete
return default
[106] Fix | Delete
[107] Fix | Delete
def __getitem__(self, key):
[108] Fix | Delete
try:
[109] Fix | Delete
value = self.cache[key]
[110] Fix | Delete
except KeyError:
[111] Fix | Delete
f = BytesIO(self.dict[key.encode(self.keyencoding)])
[112] Fix | Delete
value = Unpickler(f).load()
[113] Fix | Delete
if self.writeback:
[114] Fix | Delete
self.cache[key] = value
[115] Fix | Delete
return value
[116] Fix | Delete
[117] Fix | Delete
def __setitem__(self, key, value):
[118] Fix | Delete
if self.writeback:
[119] Fix | Delete
self.cache[key] = value
[120] Fix | Delete
f = BytesIO()
[121] Fix | Delete
p = Pickler(f, self._protocol)
[122] Fix | Delete
p.dump(value)
[123] Fix | Delete
self.dict[key.encode(self.keyencoding)] = f.getvalue()
[124] Fix | Delete
[125] Fix | Delete
def __delitem__(self, key):
[126] Fix | Delete
del self.dict[key.encode(self.keyencoding)]
[127] Fix | Delete
try:
[128] Fix | Delete
del self.cache[key]
[129] Fix | Delete
except KeyError:
[130] Fix | Delete
pass
[131] Fix | Delete
[132] Fix | Delete
def __enter__(self):
[133] Fix | Delete
return self
[134] Fix | Delete
[135] Fix | Delete
def __exit__(self, type, value, traceback):
[136] Fix | Delete
self.close()
[137] Fix | Delete
[138] Fix | Delete
def close(self):
[139] Fix | Delete
if self.dict is None:
[140] Fix | Delete
return
[141] Fix | Delete
try:
[142] Fix | Delete
self.sync()
[143] Fix | Delete
try:
[144] Fix | Delete
self.dict.close()
[145] Fix | Delete
except AttributeError:
[146] Fix | Delete
pass
[147] Fix | Delete
finally:
[148] Fix | Delete
# Catch errors that may happen when close is called from __del__
[149] Fix | Delete
# because CPython is in interpreter shutdown.
[150] Fix | Delete
try:
[151] Fix | Delete
self.dict = _ClosedDict()
[152] Fix | Delete
except:
[153] Fix | Delete
self.dict = None
[154] Fix | Delete
[155] Fix | Delete
def __del__(self):
[156] Fix | Delete
if not hasattr(self, 'writeback'):
[157] Fix | Delete
# __init__ didn't succeed, so don't bother closing
[158] Fix | Delete
# see http://bugs.python.org/issue1339007 for details
[159] Fix | Delete
return
[160] Fix | Delete
self.close()
[161] Fix | Delete
[162] Fix | Delete
def sync(self):
[163] Fix | Delete
if self.writeback and self.cache:
[164] Fix | Delete
self.writeback = False
[165] Fix | Delete
for key, entry in self.cache.items():
[166] Fix | Delete
self[key] = entry
[167] Fix | Delete
self.writeback = True
[168] Fix | Delete
self.cache = {}
[169] Fix | Delete
if hasattr(self.dict, 'sync'):
[170] Fix | Delete
self.dict.sync()
[171] Fix | Delete
[172] Fix | Delete
[173] Fix | Delete
class BsdDbShelf(Shelf):
[174] Fix | Delete
"""Shelf implementation using the "BSD" db interface.
[175] Fix | Delete
[176] Fix | Delete
This adds methods first(), next(), previous(), last() and
[177] Fix | Delete
set_location() that have no counterpart in [g]dbm databases.
[178] Fix | Delete
[179] Fix | Delete
The actual database must be opened using one of the "bsddb"
[180] Fix | Delete
modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or
[181] Fix | Delete
bsddb.rnopen) and passed to the constructor.
[182] Fix | Delete
[183] Fix | Delete
See the module's __doc__ string for an overview of the interface.
[184] Fix | Delete
"""
[185] Fix | Delete
[186] Fix | Delete
def __init__(self, dict, protocol=None, writeback=False,
[187] Fix | Delete
keyencoding="utf-8"):
[188] Fix | Delete
Shelf.__init__(self, dict, protocol, writeback, keyencoding)
[189] Fix | Delete
[190] Fix | Delete
def set_location(self, key):
[191] Fix | Delete
(key, value) = self.dict.set_location(key)
[192] Fix | Delete
f = BytesIO(value)
[193] Fix | Delete
return (key.decode(self.keyencoding), Unpickler(f).load())
[194] Fix | Delete
[195] Fix | Delete
def next(self):
[196] Fix | Delete
(key, value) = next(self.dict)
[197] Fix | Delete
f = BytesIO(value)
[198] Fix | Delete
return (key.decode(self.keyencoding), Unpickler(f).load())
[199] Fix | Delete
[200] Fix | Delete
def previous(self):
[201] Fix | Delete
(key, value) = self.dict.previous()
[202] Fix | Delete
f = BytesIO(value)
[203] Fix | Delete
return (key.decode(self.keyencoding), Unpickler(f).load())
[204] Fix | Delete
[205] Fix | Delete
def first(self):
[206] Fix | Delete
(key, value) = self.dict.first()
[207] Fix | Delete
f = BytesIO(value)
[208] Fix | Delete
return (key.decode(self.keyencoding), Unpickler(f).load())
[209] Fix | Delete
[210] Fix | Delete
def last(self):
[211] Fix | Delete
(key, value) = self.dict.last()
[212] Fix | Delete
f = BytesIO(value)
[213] Fix | Delete
return (key.decode(self.keyencoding), Unpickler(f).load())
[214] Fix | Delete
[215] Fix | Delete
[216] Fix | Delete
class DbfilenameShelf(Shelf):
[217] Fix | Delete
"""Shelf implementation using the "dbm" generic dbm interface.
[218] Fix | Delete
[219] Fix | Delete
This is initialized with the filename for the dbm database.
[220] Fix | Delete
See the module's __doc__ string for an overview of the interface.
[221] Fix | Delete
"""
[222] Fix | Delete
[223] Fix | Delete
def __init__(self, filename, flag='c', protocol=None, writeback=False):
[224] Fix | Delete
import dbm
[225] Fix | Delete
Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
[226] Fix | Delete
[227] Fix | Delete
[228] Fix | Delete
def open(filename, flag='c', protocol=None, writeback=False):
[229] Fix | Delete
"""Open a persistent dictionary for reading and writing.
[230] Fix | Delete
[231] Fix | Delete
The filename parameter is the base filename for the underlying
[232] Fix | Delete
database. As a side-effect, an extension may be added to the
[233] Fix | Delete
filename and more than one file may be created. The optional flag
[234] Fix | Delete
parameter has the same interpretation as the flag parameter of
[235] Fix | Delete
dbm.open(). The optional protocol parameter specifies the
[236] Fix | Delete
version of the pickle protocol.
[237] Fix | Delete
[238] Fix | Delete
See the module's __doc__ string for an overview of the interface.
[239] Fix | Delete
"""
[240] Fix | Delete
[241] Fix | Delete
return DbfilenameShelf(filename, flag, protocol, writeback)
[242] Fix | Delete
[243] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function