1 """Utilities package for NDG XACML
2
3 NERC DataGrid
4 """
5 __author__ = "P J Kershaw"
6 __date__ = "02/04/09"
7 __copyright__ = ""
8 __license__ = "BSD - see LICENSE file in top-level directory"
9 __contact__ = "Philip.Kershaw@stfc.ac.uk"
10 __revision__ = '$Id: __init__.py 7324 2010-08-13 14:20:05Z pjkersha $'
11 import UserDict
12
13
14 str2Bool = lambda str: str.lower() in ("yes", "true", "t", "1")
15
17 """Extended version of list type to enable a list with unique items.
18 If an item is added that is already present then it is silently omitted
19 from the list
20 """
21
23 """Extend a list with input iterable
24 @param iter: iterable object
25 @type iter: iterable type
26 """
27 return super(UniqList, self).extend([i for i in iter if i not in self])
28
30 """Extend a list with input iterable
31 @param iter: iterable object
32 @type iter: iterable type
33 """
34 return super(UniqList, self).__iadd__([i for i in iter
35 if i not in self])
36
38 """Add an item to the list
39 @param item: item to append to list
40 @type item: any
41 """
42 for i in self:
43 if i == item:
44 return None
45
46 return super(UniqList, self).append(item)
47
48
50 """Extend list type to enabled only items of a given type. Supports
51 any type where the array type in the Standard Library is restricted to
52 only limited set of primitive types
53 """
54
55 - def __init__(self, elementType, *arg, **kw):
56 """
57 @type elementType: type/tuple
58 @param elementType: object type or types which the list is allowed to
59 contain. If more than one type, pass as a tuple
60 """
61 self.__elementType = elementType
62 super(TypedList, self).__init__(*arg, **kw)
63
65 """@return: represent instance giving type information about the
66 elements
67 @rtype: string
68 """
69 return "%r type: %s" % (self.__elementType,
70 super(TypedList, self).__repr__())
71
73 """@return: the element type for this list
74 @rtype: type
75 """
76 return self.__elementType
77
78 elementType = property(fget=_getElementType,
79 doc="The allowed type or types for list elements")
80
82 """Extend a list with input iterable
83 @param iter: iterable object
84 @type iter: iterable type
85 @raise TypeError: input item doesn't match list type
86 """
87 for i in iter:
88 if not isinstance(i, self.__elementType):
89 raise TypeError("List items must be of type %s" %
90 (self.__elementType,))
91
92 return super(TypedList, self).extend(iter)
93
95 """Extend a list with input iterable
96 @param iter: iterable object
97 @type iter: iterable type
98 @raise TypeError: input item doesn't match list type
99 """
100 for i in iter:
101 if not isinstance(i, self.__elementType):
102 raise TypeError("List items must be of type %s" %
103 (self.__elementType,))
104
105 return super(TypedList, self).__iadd__(iter)
106
108 """Add an item to the list
109 @param iter: iterable object
110 @type iter: iterable type
111 @raise TypeError: input item doesn't match list type
112 """
113 if not isinstance(item, self.__elementType):
114 raise TypeError("List items must be of type %s" %
115 (self.__elementType,))
116
117 return super(TypedList, self).append(item)
118
119
121 """Utility class for holding a constrained list of key names
122 """
123
125 """Alter standard dict() initialisation to fix key names set at
126 initialisation
127 """
128 super(RestrictedKeyNamesDict, self).__init__(*arg, **kw)
129 self.__keyNames = self.keys()
130
132 """@param key: key for item to set
133 @type key: any
134 @param val: value to set for this key
135 @type val: any
136 """
137 if key not in self.__keyNames:
138 raise KeyError('Key name %r not recognised. Valid key names '
139 'are: %r' % (key, self.__keyNames))
140
141 dict.__setitem__(self, key, val)
142
144 """@param d: dictionary to update from
145 @type d: dict
146 @param kw: keywords to update dictionary with
147 @type kw: dict
148 """
149 for dictArg in (d, kw):
150 for k in dictArg:
151 if k not in self.__keyNames:
152 raise KeyError('Key name "%s" not recognised. Valid '
153 'key names are: %s' %
154 self.__keyNames)
155
156 dict.update(self, d, **kw)
157
158
159 _isIterable = lambda obj: getattr(obj, '__iter__', False)
160
161
163 """Enforce custom checking on keys and items before addition to a
164 dictionary
165 """
166
168 """Initialise setting the allowed type or types for keys and items
169
170 @param args: two arguments: the first is a callable which filters for
171 permissable keys in this dict, the second sets the type or list of
172 types permissable for items in this dict
173 @type args: tuple
174 """
175 if len(args) != 2:
176 raise TypeError('__init__() takes 2 arguments, KeyFilter and '
177 'valueFilter (%d given)' % len(args))
178
179
180 for arg, argName in zip(args, ('KeyFilter', 'valueFilter')):
181 if not callable(arg):
182 raise TypeError('Expecting callable for %r input; got %r' %
183 (argName, type(arg)))
184
185 self.__KeyFilter, self.__valueFilter = args
186
187 self.__map = {}
188
190 """Check given key value pair and return False if they should be
191 filtered out. Filter functions may also raise an exception if they
192 wish to abort completely
193
194 @param key: dict key to check
195 @type key: basestring
196 @param val: value to check
197 @type val: any
198 """
199 if not self.__KeyFilter(key):
200 return False
201
202 elif not self.__valueFilter(val):
203 return False
204
205 else:
206 return True
207
209 """Enforce type checking when setting new items
210
211 @param key: key for item to set
212 @type key: any
213 @param val: value to set for this key
214 @type val: any
215 """
216 if self._verifyKeyValPair(key, val):
217 self.__map[key] = val
218
220 """Provide implementation for getting items
221 @param key: key for item to retrieve
222 @type key: any
223 @return: value for input key
224 @rtype: any
225 """
226 if key not in self.__map:
227 raise KeyError('%r key not found in dict' % key)
228
229 return self.__map[key]
230
231 - def get(self, key, *arg):
232 """Provide implementation of get item with default
233
234 @param key: key for item to retrieve
235 @type key: any
236 @param arg: use to set a default argument
237 @type arg: tuple
238 """
239 if key in self.__map:
240 return self.__map[key]
241
242 elif len(arg) > 1:
243
244 return arg[1]
245 else:
246 return None
247
249 return repr(self.__map)
250
253
256
259
262