blob: 9d5eac0746e6215a0583413f7ad26883af47c40a [file] [log] [blame]
Fred Drake41deb1e2001-02-01 05:27:45 +00001"""Weak reference support for Python.
2
3This module is an implementation of PEP 205:
4
5http://python.sourceforge.net/peps/pep-0205.html
6"""
7
8import UserDict
9
10from _weakref import \
11 getweakrefcount, \
12 getweakrefs, \
13 ref, \
14 proxy, \
15 ReferenceError, \
16 CallableProxyType, \
17 ProxyType, \
18 ReferenceType
19
20ProxyTypes = (ProxyType, CallableProxyType)
21
22
Martin v. Löwis5e163332001-02-27 18:36:56 +000023def mapping(dict=None,weakkeys=0):
24 if weakkeys:
25 return WeakKeyDictionary(dict)
26 else:
27 return WeakValueDictionary(dict)
Fred Drake41deb1e2001-02-01 05:27:45 +000028
29
Martin v. Löwis5e163332001-02-27 18:36:56 +000030class WeakValueDictionary(UserDict.UserDict):
Fred Drake41deb1e2001-02-01 05:27:45 +000031
32 # We inherit the constructor without worrying about the input
33 # dictionary; since it uses our .update() method, we get the right
34 # checks (if the other dictionary is a WeakDictionary, objects are
35 # unwrapped on the way out, and we always wrap on the way in).
36
37 def __getitem__(self, key):
38 o = self.data.get(key)()
39 if o is None:
40 raise KeyError, key
41 else:
42 return o
43
44 def __repr__(self):
45 return "<WeakDictionary at %s>" % id(self)
46
47 def __setitem__(self, key, value):
48 def remove(o, data=self.data, key=key):
49 del data[key]
50 self.data[key] = ref(value, remove)
51
52 def copy(self):
53 new = WeakDictionary()
54 for key, ref in self.data.items():
55 o = ref()
56 if o is not None:
57 new[key] = o
58
59 def get(self, key, default):
60 try:
61 ref = self.data[key]
62 except KeyError:
63 return default
64 else:
65 o = ref()
66 if o is None:
67 # This should only happen
68 return default
69 else:
70 return o
71
72 def items(self):
Fred Drake312a5dc2001-02-02 15:13:24 +000073 L = []
74 for key, ref in self.data.items():
Fred Drake41deb1e2001-02-01 05:27:45 +000075 o = ref()
76 if o is not None:
Fred Drake312a5dc2001-02-02 15:13:24 +000077 L.append((key, o))
Fred Drake41deb1e2001-02-01 05:27:45 +000078 return L
79
80 def popitem(self):
81 while 1:
82 key, ref = self.data.popitem()
83 o = ref()
84 if o is not None:
85 return key, o
86
87 def setdefault(self, key, default):
88 try:
89 ref = self.data[key]
90 except KeyError:
91 def remove(o, data=self.data, key=key):
92 del data[key]
93 ref = ref(default, remove)
94 self.data[key] = ref
95 return default
96 else:
97 return ref()
98
99 def update(self, dict):
100 d = self.data
101 L = []
102 for key, o in dict.items():
103 def remove(o, data=d, key=key):
104 del data[key]
105 L.append(key, ref(o, remove))
106 for key, r in L:
107 d[key] = r
108
109 def values(self):
110 L = []
111 for ref in self.data.values():
112 o = ref()
113 if o is not None:
114 L.append(o)
115 return L
116
117
Martin v. Löwis5e163332001-02-27 18:36:56 +0000118class WeakKeyDictionary(UserDict.UserDict):
119
120 def __init__(self, dict=None):
121 self.data = {}
122 if dict is not None: self.update(dict)
123 def remove(k, data=self.data):
124 del data[k]
125 self._remove = remove
126
127 def __getitem__(self, key):
128 return self.data[ref(key)]
129
130 def __repr__(self):
131 return "<WeakKeyDictionary at %s>" % id(self)
132
133 def __setitem__(self, key, value):
134 self.data[ref(key, self._remove)] = value
135
136 def copy(self):
137 new = WeakKeyDictionary()
138 for key, value in self.data.items():
139 o = key()
140 if o is not None:
141 new[o] = value
142
143 def get(self, key, default):
144 return self.data.get(ref(key),default)
145
146 def items(self):
147 L = []
148 for key, value in self.data.items():
149 o = key()
150 if o is not None:
151 L.append((o, value))
152 return L
153
154 def popitem(self):
155 while 1:
156 key, value = self.data.popitem()
157 o = key()
158 if o is not None:
159 return o, value
160
161 def setdefault(self, key, default):
162 return self.data.setdefault(ref(key, self._remove),default)
163
164 def update(self, dict):
165 d = self.data
166 L = []
167 for key, value in dict.items():
168 L.append(ref(key, self._remove), value)
169 for key, r in L:
170 d[key] = r
171
Fred Drake41deb1e2001-02-01 05:27:45 +0000172# no longer needed
173del UserDict