1"""
2$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/durus/persistent_dict.py $
3$Id: persistent_dict.py 30862 2008-06-18 14:13:35Z dbinger $
4"""
5from copy import copy
6from durus.persistent import PersistentObject
7from durus.utils import iteritems
8
9class PersistentDict (PersistentObject):
10    """
11    Instance attributes:
12      data : dict
13    """
14    __slots__ = ['data']
15
16    data_is = dict # for type checking using QP's spec module
17
18    def __init__(self, *args, **kwargs):
19        self.data = dict(*args, **kwargs)
20
21    def __eq__(self, other):
22        return isinstance(other, PersistentDict) and self.data == other.data
23
24    def __ne__(self, other):
25        return not self == other
26
27    def __len__(self):
28        return len(self.data)
29
30    def __getitem__(self, key):
31        return self.data[key]
32
33    def __setitem__(self, key, item):
34        self._p_note_change()
35        self.data[key] = item
36
37    def __delitem__(self, key):
38        self._p_note_change()
39        del self.data[key]
40
41    def clear(self):
42        self._p_note_change()
43        self.data.clear()
44
45    def copy(self):
46        result = copy(self)
47        result.data = self.data.copy()
48        return result
49
50    def keys(self):
51        return list(self.data.keys())
52
53    def items(self):
54        return list(self.data.items())
55
56    def iteritems(self):
57        return iteritems(self.data)
58
59    def iterkeys(self):
60        for k, v in self.iteritems():
61            yield k
62
63    def itervalues(self):
64        for k, v in self.iteritems():
65            yield v
66
67    def values(self):
68        return list(self.data.values())
69
70    def has_key(self, key):
71        return key in self.data
72
73    def update(self, *others, **kwargs):
74        self._p_note_change()
75        if len(others) > 1:
76            raise TypeError("update() expected at most 1 argument")
77        elif others:
78            other = others[0]
79            if isinstance(other, PersistentDict):
80                self.data.update(other.data)
81            elif isinstance(other, dict):
82                self.data.update(other)
83            elif hasattr(other, 'keys'):
84                for k in other.keys():
85                    self[k] = other[k]
86            else:
87                for k, v in other:
88                    self[k] = v
89        for kw in kwargs:
90            self[kw] = kwargs[kw]
91
92    def get(self, key, failobj=None):
93        return self.data.get(key, failobj)
94
95    def setdefault(self, key, failobj=None):
96        if key not in self.data:
97            self._p_note_change()
98            self.data[key] = failobj
99            return failobj
100        return self.data[key]
101
102    def pop(self, key, *args):
103        self._p_note_change()
104        return self.data.pop(key, *args)
105
106    def popitem(self):
107        self._p_note_change()
108        return self.data.popitem()
109
110    def __contains__(self, key):
111        return key in self.data
112
113    def fromkeys(cls, iterable, value=None):
114        d = cls()
115        for key in iterable:
116            d[key] = value
117        return d
118    fromkeys = classmethod(fromkeys)
119
120    def __iter__(self):
121        return iter(self.data)
122
123
124