Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7994716

Browse files
committed
SF patch #520382: Expand shelve.py to have a full dictionary interface
and add a mixin to UserDict.py to make it easier to implement a full dictionary interface.
1 parent 3a7f405 commit 7994716

5 files changed

Lines changed: 104 additions & 2 deletions

File tree

Doc/lib/libshelve.tex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ \section{\module{shelve} ---
3333
d.close() # close it
3434
\end{verbatim}
3535

36+
In addition to the above, shelve supports all methods that are
37+
supported by dictionaries. This eases the transition from dictionary
38+
based scripts to those requiring persistent storage.
39+
3640
Restrictions:
3741

3842
\begin{itemize}

Doc/lib/libuserdict.tex

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ \section{\module{UserDict} ---
1515
them and override existing methods or add new ones. In this way one
1616
can add new behaviors to dictionaries.
1717

18-
The \module{UserDict} module defines the \class{UserDict} class:
18+
The module also defines a mixin defining all dictionary methods for
19+
classes that already have a minimum mapping interface. This greatly
20+
simplifies writing classes that need to be substitutable for
21+
dictionaries (such as the shelve module).
22+
23+
The \module{UserDict} module defines the \class{UserDict} class
24+
and \class{DictMixin}:
1925

2026
\begin{classdesc}{UserDict}{\optional{initialdata}}
2127
Class that simulates a dictionary. The instance's
@@ -35,6 +41,23 @@ \section{\module{UserDict} ---
3541
class.
3642
\end{memberdesc}
3743

44+
\begin{classdesc}{DictMixin}{}
45+
Mixin defining all dictionary methods for classes that already have
46+
a minimum dictionary interface including\method{__getitem__},
47+
\method{__setitem__}, \method{__delitem__}, and \method{keys}.
48+
49+
This mixin should be used as a superclass. Adding each of the
50+
above methods adds progressively more functionality. For instance,
51+
the absence of \method{__delitem__} precludes only \method{pop}
52+
and \method{popitem}.
53+
54+
While the four methods listed above are sufficient to support the
55+
entire dictionary interface, progessively more efficiency comes
56+
with defining \method{__contains__}, \method{__iter__}, and
57+
\method{iteritems}.
58+
59+
\end{classdesc}
60+
3861

3962
\section{\module{UserList} ---
4063
Class wrapper for list objects}

Lib/UserDict.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,67 @@ def __contains__(self, key):
6060
class IterableUserDict(UserDict):
6161
def __iter__(self):
6262
return iter(self.data)
63+
64+
class DictMixin:
65+
'''Mixin defining all dictionary methods for classes that already have
66+
a minimum dictionary interface including getitem, setitem, delitem,
67+
and keys '''
68+
69+
# first level provided by subclass: getitem, setitem, delitem, and keys
70+
71+
# second level definitions which assume only getitem and keys
72+
def has_key(self, key):
73+
try:
74+
value = self[key]
75+
except KeyError:
76+
return False
77+
return True
78+
__contains__ = has_key
79+
def __iter__(self):
80+
for k in self.keys():
81+
yield k
82+
def __len__(self):
83+
return len(self.keys())
84+
85+
# third level uses second level instead of first
86+
def iteritems(self):
87+
for k in self:
88+
yield (k, self[k])
89+
iterkeys = __iter__
90+
91+
# fourth level uses second and third levels instead of first
92+
def itervalues(self):
93+
for _, v in self.iteritems():
94+
yield v
95+
def values(self):
96+
return [self[key] for key in self.keys()]
97+
def items(self):
98+
return list(self.iteritems())
99+
def clear(self):
100+
for key in self.keys():
101+
del self[key]
102+
def setdefault(self, key, default):
103+
if key not in self:
104+
self[key] = default
105+
return default
106+
return self[key]
107+
def pop(self, key):
108+
value = self[key]
109+
del self[key]
110+
return value
111+
def popitem(self):
112+
try:
113+
k, v = self.iteritems().next()
114+
except StopIteration:
115+
raise KeyError, 'dictionary is empty'
116+
del self[k]
117+
return (k, v)
118+
def update(self, other):
119+
for key in other.keys():
120+
self[key] = other[key]
121+
def get(self, key, default=None):
122+
if key in self:
123+
return self[key]
124+
return default
125+
def __repr__(self):
126+
return repr(dict(self.items()))

Lib/shelve.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@
4040
except ImportError:
4141
from StringIO import StringIO
4242

43+
import UserDict
44+
4345
__all__ = ["Shelf","BsdDbShelf","DbfilenameShelf","open"]
4446

45-
class Shelf:
47+
class Shelf(UserDict.DictMixin):
4648
"""Base class for shelf implementations.
4749
4850
This is initialized with a dictionary-like object.

Misc/NEWS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,15 @@ Extension modules
381381
Library
382382
-------
383383

384+
- UserDict.py now defines a DictMixin class which defines all dictionary
385+
methods for classes that already have a minimum mapping interface.
386+
This greatly simplifies writing classes that need to be substitutable
387+
for dictionaries (such as the shelve module).
388+
389+
- shelve.py now subclasses from UserDict.DictMixin. Now shelve supports
390+
all dictionary methods. This eases the transition to persistent
391+
storage for scripts originally written with dictionaries in mind.
392+
384393
- A new package, logging, implements the logging API defined by PEP
385394
282. The code is written by Vinay Sajip.
386395

0 commit comments

Comments
 (0)