Show More
@@ -111,7 +111,7 b' class ColorScheme:' | |||
|
111 | 111 | """Return a full copy of the object, optionally renaming it.""" |
|
112 | 112 | if name is None: |
|
113 | 113 | name = self.name |
|
114 |
return ColorScheme(name,self.colors. |
|
|
114 | return ColorScheme(name, self.colors.dict()) | |
|
115 | 115 | |
|
116 | 116 | class ColorSchemeTable(dict): |
|
117 | 117 | """General class to handle tables of color schemes. |
@@ -11,12 +11,13 b'' | |||
|
11 | 11 | |
|
12 | 12 | __all__ = ['Struct'] |
|
13 | 13 | |
|
14 | import inspect | |
|
14 | 15 | import types |
|
15 | 16 | import pprint |
|
16 | 17 | |
|
17 | 18 | from IPython.utils.genutils import list2dict2 |
|
18 | 19 | |
|
19 | class Struct: | |
|
20 | class Struct(object): | |
|
20 | 21 | """Class to mimic C structs but also provide convenient dictionary-like |
|
21 | 22 | functionality. |
|
22 | 23 | |
@@ -105,75 +106,72 b' class Struct:' | |||
|
105 | 106 | 'merge popitem setdefault update values ' |
|
106 | 107 | '__make_dict __dict_invert ').split() |
|
107 | 108 | |
|
108 |
def __init__(self,d |
|
|
109 |
"""Initialize with a dictionary, another Struct, or |
|
|
110 | explicitly the list of attributes. | |
|
109 | def __init__(self,data=None,**kw): | |
|
110 | """Initialize with a dictionary, another Struct, or data. | |
|
111 | ||
|
112 | Parameters | |
|
113 | ---------- | |
|
114 | data : dict, Struct | |
|
115 | Initialize with this data. | |
|
116 | kw : dict | |
|
117 | Initialize with key, value pairs. | |
|
118 | ||
|
119 | Examples | |
|
120 | -------- | |
|
111 | 121 | |
|
112 | Both can be used, but the dictionary must come first: | |
|
113 | Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2). | |
|
114 | 122 | """ |
|
115 |
self |
|
|
116 | if dict is None: | |
|
117 | dict = {} | |
|
118 | if isinstance(dict,Struct): | |
|
119 | dict = dict.dict() | |
|
120 | elif dict and type(dict) is not types.DictType: | |
|
121 | raise TypeError,\ | |
|
122 |
|
|
|
123 |
d |
|
|
123 | object.__setattr__(self, '_allownew', True) | |
|
124 | object.__setattr__(self, '_data',{}) | |
|
125 | if data is None: | |
|
126 | data = {} | |
|
127 | if isinstance(data, Struct): | |
|
128 | data = data.dict() | |
|
129 | elif data and not isinstance(data, dict): | |
|
130 | raise TypeError('initialize with a dict, Struct or key=val pairs') | |
|
131 | data.update(kw) | |
|
124 | 132 | # do the updating by hand to guarantee that we go through the |
|
125 | 133 | # safety-checked __setitem__ |
|
126 |
for k,v in d |
|
|
134 | for k, v in data.items(): | |
|
127 | 135 | self[k] = v |
|
128 | 136 | |
|
129 | ||
|
130 | 137 | def __setitem__(self,key,value): |
|
131 | 138 | """Used when struct[key] = val calls are made.""" |
|
132 | if key in Struct.__protected: | |
|
133 | raise KeyError,'Key '+`key`+' is a protected key of class Struct.' | |
|
134 | if not self['__allownew'] and key not in self.__dict__: | |
|
139 | if isinstance(key, str): | |
|
140 | # I can't simply call hasattr here because it calls getattr, which | |
|
141 | # calls self.__getattr__, which returns True for keys in | |
|
142 | # self._data. But I only want keys in the class and in | |
|
143 | # self.__dict__ | |
|
144 | if key in self.__dict__ or hasattr(Struct, key): | |
|
135 | 145 | raise KeyError( |
|
136 | "Can't create unknown attribute %s - Check for typos, or use allow_new_attr to create new attributes!" % | |
|
137 |
|
|
|
138 | ||
|
139 | self.__dict__[key] = value | |
|
146 | 'key %s is a protected key of class Struct.' % key | |
|
147 | ) | |
|
148 | if not self._allownew and key not in self._data: | |
|
149 | raise KeyError( | |
|
150 | "can't create unknown attribute %s. Check for typos, or use allow_new_attr" % key) | |
|
151 | self._data[key] = value | |
|
140 | 152 | |
|
141 | 153 | def __setattr__(self, key, value): |
|
142 | """Used when struct.key = val calls are made.""" | |
|
143 | 154 | self.__setitem__(key,value) |
|
144 | 155 | |
|
145 |
def __ |
|
|
146 | """Gets called by print.""" | |
|
156 | def __getattr__(self, key): | |
|
157 | try: | |
|
158 | result = self._data[key] | |
|
159 | except KeyError: | |
|
160 | raise AttributeError(key) | |
|
161 | else: | |
|
162 | return result | |
|
163 | ||
|
164 | def __getitem__(self, key): | |
|
165 | return self._data[key] | |
|
147 | 166 | |
|
148 | return 'Struct('+ pprint.pformat(self.__dict__)+')' | |
|
167 | def __str__(self): | |
|
168 | return 'Struct('+ pprint.pformat(self._data)+')' | |
|
149 | 169 | |
|
150 | 170 | def __repr__(self): |
|
151 | """Gets called by repr. | |
|
152 | ||
|
153 | A Struct can be recreated with S_new=eval(repr(S_old)).""" | |
|
154 | 171 | return self.__str__() |
|
155 | 172 | |
|
156 | def __getitem__(self,key): | |
|
157 | """Allows struct[key] access.""" | |
|
158 | return self.__dict__[key] | |
|
159 | ||
|
160 | 173 | def __contains__(self,key): |
|
161 | """Allows use of the 'in' operator. | |
|
162 | ||
|
163 | Examples: | |
|
164 | >>> s = Struct(x=1) | |
|
165 | >>> 'x' in s | |
|
166 | True | |
|
167 | >>> 'y' in s | |
|
168 | False | |
|
169 | >>> s[4] = None | |
|
170 | >>> 4 in s | |
|
171 | True | |
|
172 | >>> s.z = None | |
|
173 | >>> 'z' in s | |
|
174 | True | |
|
175 | """ | |
|
176 | return key in self.__dict__ | |
|
174 | return key in self._data | |
|
177 | 175 | |
|
178 | 176 | def __iadd__(self,other): |
|
179 | 177 | """S += S2 is a shorthand for S.merge(S2).""" |
@@ -181,49 +179,47 b' class Struct:' | |||
|
181 | 179 | return self |
|
182 | 180 | |
|
183 | 181 | def __add__(self,other): |
|
184 |
"""S + S2 -> New Struct made f |
|
|
182 | """S + S2 -> New Struct made from S.merge(S2)""" | |
|
185 | 183 | Sout = self.copy() |
|
186 | 184 | Sout.merge(other) |
|
187 | 185 | return Sout |
|
188 | 186 | |
|
189 | 187 | def __sub__(self,other): |
|
190 | """Return S1-S2, where all keys in S2 have been deleted (if present) | |
|
191 | from S1.""" | |
|
188 | """Out of place remove keys from self that are in other.""" | |
|
192 | 189 | Sout = self.copy() |
|
193 | 190 | Sout -= other |
|
194 | 191 | return Sout |
|
195 | 192 | |
|
196 | 193 | def __isub__(self,other): |
|
197 | """Do in place S = S - S2, meaning all keys in S2 have been deleted | |
|
198 | (if present) from S1.""" | |
|
199 | ||
|
194 | """Inplace remove keys from self that are in other.""" | |
|
200 | 195 | for k in other.keys(): |
|
201 | 196 | if self.has_key(k): |
|
202 |
del self._ |
|
|
197 | del self._data[k] | |
|
203 | 198 | |
|
204 | 199 | def __make_dict(self,__loc_data__,**kw): |
|
205 |
"Helper function for update and merge. Return a dict from data. |
|
|
206 | ||
|
200 | """Helper function for update and merge. Return a dict from data. | |
|
201 | """ | |
|
207 | 202 | if __loc_data__ == None: |
|
208 |
d |
|
|
209 |
elif |
|
|
210 |
d |
|
|
203 | data = {} | |
|
204 | elif isinstance(__loc_data__, dict): | |
|
205 | data = __loc_data__ | |
|
211 | 206 | elif isinstance(__loc_data__,Struct): |
|
212 |
d |
|
|
207 | data = __loc_data__._data | |
|
213 | 208 | else: |
|
214 |
raise TypeError |
|
|
209 | raise TypeError('update with a dict, Struct or key=val pairs') | |
|
215 | 210 | if kw: |
|
216 |
d |
|
|
217 |
return d |
|
|
211 | data.update(kw) | |
|
212 | return data | |
|
218 | 213 | |
|
219 |
def __dict_invert(self, |
|
|
220 |
"""Helper function for merge. |
|
|
221 | lists and returns a dict. with the elements of each list as keys and | |
|
222 | the original keys as values.""" | |
|
214 | def __dict_invert(self, data): | |
|
215 | """Helper function for merge. | |
|
223 | 216 | |
|
217 | Takes a dictionary whose values are lists and returns a dict with | |
|
218 | the elements of each list as keys and the original keys as values. | |
|
219 | """ | |
|
224 | 220 | outdict = {} |
|
225 |
for k,lst in d |
|
|
226 |
if |
|
|
221 | for k,lst in data.items(): | |
|
222 | if isinstance(lst, str): | |
|
227 | 223 | lst = lst.split() |
|
228 | 224 | for entry in lst: |
|
229 | 225 | outdict[entry] = k |
@@ -231,36 +227,43 b' class Struct:' | |||
|
231 | 227 | |
|
232 | 228 | def clear(self): |
|
233 | 229 | """Clear all attributes.""" |
|
234 |
self._ |
|
|
230 | self._data.clear() | |
|
235 | 231 | |
|
236 | 232 | def copy(self): |
|
237 | 233 | """Return a (shallow) copy of a Struct.""" |
|
238 |
return Struct(self._ |
|
|
234 | return Struct(self._data.copy()) | |
|
239 | 235 | |
|
240 | 236 | def dict(self): |
|
241 | 237 | """Return the Struct's dictionary.""" |
|
242 |
return self._ |
|
|
238 | return self._data | |
|
243 | 239 | |
|
244 | 240 | def dictcopy(self): |
|
245 | 241 | """Return a (shallow) copy of the Struct's dictionary.""" |
|
246 |
return self._ |
|
|
242 | return self._data.copy() | |
|
247 | 243 | |
|
248 | 244 | def popitem(self): |
|
249 | """S.popitem() -> (k, v), remove and return some (key, value) pair as | |
|
250 | a 2-tuple; but raise KeyError if S is empty.""" | |
|
251 | return self.__dict__.popitem() | |
|
245 | """Return (key, value) tuple and remove from Struct. | |
|
252 | 246 | |
|
253 | def update(self,__loc_data__=None,**kw): | |
|
254 | """Update (merge) with data from another Struct or from a dictionary. | |
|
255 | Optionally, one or more key=value pairs can be given at the end for | |
|
256 | direct update.""" | |
|
247 | If key is not present raise KeyError. | |
|
248 | """ | |
|
249 | return self._data.popitem() | |
|
257 | 250 | |
|
251 | def update(self,__loc_data__=None,**kw): | |
|
252 | """Update (merge) with data from another Struct or dict. | |
|
253 | ||
|
254 | Parameters | |
|
255 | ---------- | |
|
256 | __loc_data : dict, Struct | |
|
257 | The new data to add to self. | |
|
258 | kw : dict | |
|
259 | Key, value pairs to add to self. | |
|
260 | """ | |
|
258 | 261 | # The funny name __loc_data__ is to prevent a common variable name |
|
259 | 262 | # which could be a fieled of a Struct to collide with this |
|
260 | 263 | # parameter. The problem would arise if the function is called with a |
|
261 | 264 | # keyword with this same name that a user means to add as a Struct |
|
262 | 265 | # field. |
|
263 |
newdict = |
|
|
266 | newdict = self.__make_dict(__loc_data__, **kw) | |
|
264 | 267 | for k,v in newdict.iteritems(): |
|
265 | 268 | self[k] = v |
|
266 | 269 | |
@@ -319,7 +322,7 b' class Struct:' | |||
|
319 | 322 | For more complicated conflict resolution policies, you still need to |
|
320 | 323 | construct your own functions. """ |
|
321 | 324 | |
|
322 |
data_dict = |
|
|
325 | data_dict = self.__make_dict(__loc_data__,**kw) | |
|
323 | 326 | |
|
324 | 327 | # policies for conflict resolution: two argument functions which return |
|
325 | 328 | # the value that will go in the new struct |
@@ -344,7 +347,7 b' class Struct:' | |||
|
344 | 347 | if name in inv_conflict_solve_user.keys(): |
|
345 | 348 | inv_conflict_solve_user[func] = inv_conflict_solve_user[name] |
|
346 | 349 | del inv_conflict_solve_user[name] |
|
347 |
conflict_solve.update( |
|
|
350 | conflict_solve.update(self.__dict_invert(inv_conflict_solve_user)) | |
|
348 | 351 | #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg |
|
349 | 352 | #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve) |
|
350 | 353 | for key in data_dict: |
@@ -355,7 +358,7 b' class Struct:' | |||
|
355 | 358 | |
|
356 | 359 | def has_key(self,key): |
|
357 | 360 | """Like has_key() dictionary method.""" |
|
358 |
return self._ |
|
|
361 | return self._data.has_key(key) | |
|
359 | 362 | |
|
360 | 363 | def hasattr(self,key): |
|
361 | 364 | """hasattr function available as a method. |
@@ -363,32 +366,30 b' class Struct:' | |||
|
363 | 366 | Implemented like has_key, to make sure that all available keys in the |
|
364 | 367 | internal dictionary of the Struct appear also as attributes (even |
|
365 | 368 | numeric keys).""" |
|
366 |
return self._ |
|
|
369 | return self._data.has_key(key) | |
|
367 | 370 | |
|
368 | 371 | def items(self): |
|
369 |
"""Return the items in the Struct's dictionary |
|
|
370 | as a call to {}.items().""" | |
|
371 | return self.__dict__.items() | |
|
372 | """Return the items in the Struct's dictionary as (key, value)'s.""" | |
|
373 | return self._data.items() | |
|
372 | 374 | |
|
373 | 375 | def keys(self): |
|
374 |
"""Return the keys in the Struct's dictionary |
|
|
375 | as a call to {}.keys().""" | |
|
376 | return self.__dict__.keys() | |
|
376 | """Return the keys in the Struct's dictionary..""" | |
|
377 | return self._data.keys() | |
|
377 | 378 | |
|
378 | 379 | def values(self,keys=None): |
|
379 |
"""Return the values in the Struct's dictionary |
|
|
380 | as a call to {}.values(). | |
|
380 | """Return the values in the Struct's dictionary. | |
|
381 | 381 | |
|
382 | 382 | Can be called with an optional argument keys, which must be a list or |
|
383 | 383 | tuple of keys. In this case it returns only the values corresponding |
|
384 |
to those keys (allowing a form of 'slicing' for Structs). |
|
|
384 | to those keys (allowing a form of 'slicing' for Structs). | |
|
385 | """ | |
|
385 | 386 | if not keys: |
|
386 |
return self._ |
|
|
387 | return self._data.values() | |
|
387 | 388 | else: |
|
388 | ret=[] | |
|
389 | result=[] | |
|
389 | 390 | for k in keys: |
|
390 | ret.append(self[k]) | |
|
391 | return ret | |
|
391 | result.append(self[k]) | |
|
392 | return result | |
|
392 | 393 | |
|
393 | 394 | def get(self,attr,val=None): |
|
394 | 395 | """S.get(k[,d]) -> S[k] if k in S, else d. d defaults to None.""" |
@@ -399,17 +400,17 b' class Struct:' | |||
|
399 | 400 | |
|
400 | 401 | def setdefault(self,attr,val=None): |
|
401 | 402 | """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if k not in S""" |
|
402 | if not self.has_key(attr): | |
|
403 | if not self._data.has_key(attr): | |
|
403 | 404 | self[attr] = val |
|
404 | 405 | return self.get(attr,val) |
|
405 | 406 | |
|
406 | 407 | def allow_new_attr(self, allow = True): |
|
407 |
""" |
|
|
408 | """Set whether new attributes can be created in this Struct. | |
|
408 | 409 | |
|
409 | 410 | This can be used to catch typos by verifying that the attribute user |
|
410 | 411 | tries to change already exists in this Struct. |
|
411 | 412 | """ |
|
412 |
self |
|
|
413 | object.__setattr__(self, '_allownew', allow) | |
|
413 | 414 | |
|
414 | 415 | |
|
415 | 416 | # end class Struct |
General Comments 0
You need to be logged in to leave comments.
Login now