*** empty log message ***
[pli.git] / pli / pattern / mixin / mapping.py
blob49a17a9559782bd7a85d09128567845db13b8bbb
1 #=======================================================================
3 __version__ = '''0.1.03'''
4 __sub_version__ = '''20080127042744'''
5 __copyright__ = '''(c) Alex A. Naanou 2003'''
8 #-----------------------------------------------------------------------
10 _marker = 'This is a marker string... (WARNING: do not use this in any way!)'
12 # NOTE: none of the defined here classes will contaminate the namespace
13 # of the object that derrives from any one or combination of
14 # them.
16 #-----------------------------------------------------------------------
17 #-----------------------------------------------------------ismapping---
18 def ismapping(obj):
19 '''
20 '''
21 return isinstance(obj, (AbstractMapping, dict))
24 #-----------------------------------------------------------------------
25 #-----------------------------------------------------AbstractMapping---
26 class AbstractMapping(object):
27 '''
28 '''
29 pass
32 #-----------------------------------------------------------------------
33 #--------------------------------------------------------BasicMapping---
34 class BasicMapping(AbstractMapping):
35 '''
36 this defines the basic mapping interface.
37 '''
38 # root methods:
39 def __getitem__(self, key):
40 '''
41 '''
42 #raise NotImplementedError, 'root method __getitem__ not implemented.'
43 return super(BasicMapping, self).__getitem__(key)
44 def __setitem__(self, key, value):
45 '''
46 '''
47 #raise NotImplementedError, 'root method __setitem__ not implemented.'
48 return super(BasicMapping, self).__setitem__(key, value)
49 def __delitem__(self, key):
50 '''
51 '''
52 #raise NotImplementedError, 'root method __delitem__ not implemented.'
53 return super(BasicMapping, self).__delitem__(key)
54 def __iter__(self):
55 '''
56 '''
57 #raise NotImplementedError, 'root method __iter__ not implemented.'
58 return super(BasicMapping, self).__iter__()
60 # 2nd generation methods:
61 def __contains__(self, key):
62 '''
63 '''
64 try:
65 self[key]
66 return True
67 except KeyError:
68 return False
70 def __len__(self):
71 '''
72 '''
73 return len([k for k in self])
75 ## # do we need these here???
76 ## def __reduce__(self):
77 ## '''
78 ## '''
79 ## pass
80 ## def __reduce_ex__(self):
81 ## '''
82 ## '''
83 ## pass
85 ## def __repr__(self):
86 ## '''
87 ## '''
88 ## pass
89 ## def __str__(self):
90 ## '''
91 ## '''
92 ## pass
94 ## def __hash__(self):
95 ## '''
96 ## '''
97 ## pass
100 #---------------------------------------------------BasicMappingProxy---
101 # NOTE: this is slower than a direct proxy...
102 class BasicMappingProxy(AbstractMapping):
105 __source_attr__ = '__source__'
107 #__source__ = {}
109 # root methods:
110 def __getitem__(self, key):
113 return getattr(self, self.__source_attr__)[key]
114 def __setitem__(self, key, value):
117 getattr(self, self.__source_attr__)[key] = value
118 def __delitem__(self, key):
121 del getattr(self, self.__source_attr__)[key]
122 def __iter__(self):
125 return getattr(self, self.__source_attr__).__iter__()
127 # 2nd generation methods:
128 def __contains__(self, key):
131 return key in getattr(self, self.__source_attr__)
133 def __len__(self):
136 return len(getattr(self, self.__source_attr__))
139 #---------------------------------------------------ComparableMapping---
140 class ComparableMapping(BasicMapping):
142 this defines the basic comparability interface for the basic mapping.
144 # 2nd generation methods:
145 ## def __cmp__(self, other):
146 ## '''
147 ## '''
148 ## ##!!! ugly !!!##
149 ## if hasattr(other, '__iter__') and hasattr(other, '__getitem__'):
150 ## return cmp(dict([ (k, self[k]) for k in self ]), dict([ (k, other[k]) for k in other ]))
151 ## return -1
153 def __eq__(self, other):
156 if hasattr(other, '__iter__') and hasattr(other, '__getitem__'):
157 return dict([ (k, self[k]) for k in self ]) == dict([ (k, other[k]) for k in other ])
158 return False
159 def __ne__(self, other):
162 return not self == other
164 def __gt__(self, other):
167 if hasattr(other, '__iter__') and hasattr(other, '__getitem__'):
168 return dict([ (k, self[k]) for k in self ]) > dict([ (k, other[k]) for k in other ])
169 return False
170 def __lt__(self, other):
173 if hasattr(other, '__iter__') and hasattr(other, '__getitem__'):
174 return dict([ (k, self[k]) for k in self ]) < dict([ (k, other[k]) for k in other ])
175 return False
176 def __ge__(self, other):
179 if hasattr(other, '__iter__') and hasattr(other, '__getitem__'):
180 return dict([ (k, self[k]) for k in self ]) >= dict([ (k, other[k]) for k in other ])
181 return False
182 def __le__(self, other):
185 if hasattr(other, '__iter__') and hasattr(other, '__getitem__'):
186 return dict([ (k, self[k]) for k in self ]) <= dict([ (k, other[k]) for k in other ])
187 return False
190 #------------------------------------------MappingWithIteratorMethods---
191 class MappingWithIteratorMethods(BasicMapping):
193 this defines the mapping iterators.
195 # 2nd generation methods:
196 def iterkeys(self):
199 for k in self:
200 yield k
201 def itervalues(self):
204 for k in self:
205 yield self[k]
206 def iteritems(self):
209 for k in self:
210 yield k, self[k]
213 #-----------------------------------------MappingWithListConstructors---
214 class MappingWithListConstructors(BasicMapping):
216 this defines the mapping list constructors.
218 # 2nd generation methods:
219 def keys(self):
222 return list(self)
223 def values(self):
226 return [ self[k] for k in self ]
227 def items(self):
230 return [ (k, self[k]) for k in self ]
233 #-----------------------------------------------MappingWithGetMethods---
234 class MappingWithGetMethods(BasicMapping):
236 this defines the get and setdefault methods.
238 # 2nd generation methods:
239 def get(self, key, default=_marker):
242 if key in self:
243 return self[key]
244 elif default == _marker:
245 raise KeyError, (len(self) == 0 and 'get(): dictionary is empty' or '%s' % key)
246 return default
247 def setdefault(self, key, default=None):
250 if key not in self:
251 self[key] = default
252 return self.get(key, default)
255 #--------------------------------------------MappingWithModifyMethods---
256 class MappingWithModifyMethods(BasicMapping):
258 this defines the mapping in-place modification methods.
260 # 2nd generation methods:
261 def pop(self, key, default=_marker):
264 if key in self:
265 o = self[key]
266 del self[key]
267 return o
268 elif default == _marker:
269 raise KeyError, (len(self) == 0 and 'pop(): dictionary is empty' or '%s' % key)
270 return default
271 def popitem(self):
274 # fake loop!! :))
275 for k in self:
276 return k, self[k]
277 raise KeyError, 'popitem(): dictionary is empty'
279 def clear(self):
282 for k in self:
283 del self[k]
284 def update(self, data):
287 for k in data:
288 self[k] = data[k]
291 #--------------------------------------------MappingWithModifyMethods---
292 class MappingWithMappingConstructors(BasicMapping):
294 this defines mapping methods that create new mappings.
296 # 2nd generation methods:
297 def copy(self):
300 o = self.__class__()
301 for k in self:
302 o[k] = self[k]
303 return o
304 def fromkeys(self, keys, value=None):
307 o = self.__class__()
308 for k in keys:
309 o[k] = value
310 return o
313 #----------------------------------------------MappingWithTestMethods---
314 class MappingWithTestMethods(BasicMapping):
316 this defines test/predicate methods.
318 # 2nd generation methods:
319 def has_key(self, key):
322 return key in self
325 #--------------------------------------------------MappingWithMethods---
326 # Q: should this be split into finer-grained classes???
327 class MappingWithMethods(MappingWithIteratorMethods,
328 MappingWithListConstructors,
329 MappingWithGetMethods,
330 MappingWithModifyMethods,
331 MappingWithMappingConstructors,
332 MappingWithTestMethods):
334 this defines the mapping interface methods (as in dict).
336 pass
339 #-------------------------------------------------------------Mapping---
340 class Mapping(MappingWithMethods, ComparableMapping):
342 this defines the basic complete mapping.
344 pass
347 #------------------------------------------------------------DictLike---
348 class DictLike(Mapping):
350 this defines a dict like.
352 def __init__(self, *pargs, **nargs):
355 parg_len = len(pargs)
356 if parg_len not in (0, 1):
357 raise TypeError, '%s expected at most 1 arguments (got %s).' % (self.__class__, len(pargs))
358 elif parg_len == 1:
359 # seq...
360 seq = pargs[0]
361 try:
362 for i, o in enumerate(seq):
363 e = list(o)
364 if len(e) != 2:
365 raise TypeError, 'length of element %s must be 2 (got: %s).' % (i, len(e))
366 self[e[0]] = e[1]
367 except:
368 raise TypeError, 'can\'t convert element #%s of sequence to list.' % i
369 if len(nargs) > 0:
370 # mapping...
371 for k in nargs:
372 self[k] = nargs[k]
376 #=======================================================================
377 # vim:set ts=4 sw=4 nowrap :