DebugClients/Python/DebugVariables.py

changeset 5239
27f56dc07b5b
parent 5190
65a2234c6789
parent 5178
878ce843ca9f
child 5253
57276f763bf6
equal deleted inserted replaced
5228:4332a6751b14 5239:27f56dc07b5b
52 implementation 52 implementation
53 """ # __IGNORE_WARNING_D235__ 53 """ # __IGNORE_WARNING_D235__
54 raise NotImplementedError 54 raise NotImplementedError
55 55
56 56
57 ############################################################
58 ## Default Resolver
59 ############################################################
60
61
57 class DefaultResolver(BaseResolver): 62 class DefaultResolver(BaseResolver):
58 """ 63 """
59 Class used to resolve the default way. 64 Class used to resolve the default way.
60 """ 65 """
61 def resolve(self, var, attribute): 66 def resolve(self, var, attribute):
67 @param attribute name of the attribute to extract 72 @param attribute name of the attribute to extract
68 @type str 73 @type str
69 @return value of the attribute 74 @return value of the attribute
70 @rtype any 75 @rtype any
71 """ 76 """
72 return getattr(var, attribute) 77 return getattr(var, attribute, None)
73 78
74 def getDictionary(self, var): 79 def getDictionary(self, var):
75 """ 80 """
76 Public method to get the attributes of a variable as a dictionary. 81 Public method to get the attributes of a variable as a dictionary.
77 82
93 pass # if we can't get it, simply ignore it 98 pass # if we can't get it, simply ignore it
94 99
95 return d 100 return d
96 101
97 102
103 ############################################################
104 ## Resolver for Dictionaries
105 ############################################################
106
107
98 class DictResolver(BaseResolver): 108 class DictResolver(BaseResolver):
99 """ 109 """
100 Class used to resolve from a dictionary. 110 Class used to resolve from a dictionary.
101 """ 111 """
102 def resolve(self, var, attribute): 112 def resolve(self, var, attribute):
115 125
116 if "(ID:" not in attribute: 126 if "(ID:" not in attribute:
117 try: 127 try:
118 return var[attribute] 128 return var[attribute]
119 except Exception: 129 except Exception:
120 return getattr(var, attribute) 130 return getattr(var, attribute, None)
121 131
122 expectedID = int(attribute.split("(ID:")[-1][:-1]) 132 expectedID = int(attribute.split("(ID:")[-1][:-1])
123 for key, value in var.items(): 133 for key, value in var.items():
124 if id(key) == expectedID: 134 if id(key) == expectedID:
125 return value 135 return value
126 136
127 return None 137 return None
128 138
129 def __keyToStr(self, key): 139 def keyToStr(self, key):
130 """ 140 """
131 Private method to get a string representation for a key. 141 Public method to get a string representation for a key.
132 142
133 @param key key to be converted 143 @param key key to be converted
134 @type any 144 @type any
135 @return string representation of the given key 145 @return string representation of the given key
136 @rtype str 146 @rtype str
151 """ 161 """
152 d = {} 162 d = {}
153 count = 0 163 count = 0
154 for key, value in var.items(): 164 for key, value in var.items():
155 count += 1 165 count += 1
156 key = "{0} (ID:{1})".format(self.__keyToStr(key), id(key)) 166 key = "{0} (ID:{1})".format(self.keyToStr(key), id(key))
157 d[key] = value 167 d[key] = value
158 if count > MaxItemsToHandle: 168 if count > MaxItemsToHandle:
159 d[TooLargeAttribute] = TooLargeMessage 169 d[TooLargeAttribute] = TooLargeMessage
160 break 170 break
161 171
166 d.update(additionals) 176 d.update(additionals)
167 177
168 return d 178 return d
169 179
170 180
181 ############################################################
182 ## Resolver for Lists and Tuples
183 ############################################################
184
185
171 class ListResolver(BaseResolver): 186 class ListResolver(BaseResolver):
172 """ 187 """
173 Class used to resolve from a tuple or list. 188 Class used to resolve from a tuple or list.
174 """ 189 """
175 def resolve(self, var, attribute): 190 def resolve(self, var, attribute):
187 return None 202 return None
188 203
189 try: 204 try:
190 return var[int(attribute)] 205 return var[int(attribute)]
191 except Exception: 206 except Exception:
192 return getattr(var, attribute) 207 return getattr(var, attribute, None)
193 208
194 def getDictionary(self, var): 209 def getDictionary(self, var):
195 """ 210 """
196 Public method to get the attributes of a variable as a dictionary. 211 Public method to get the attributes of a variable as a dictionary.
197 212
216 d.update(additionals) 231 d.update(additionals)
217 232
218 return d 233 return d
219 234
220 235
236 ############################################################
237 ## Resolver for Sets and Frozensets
238 ############################################################
239
240
221 class SetResolver(BaseResolver): 241 class SetResolver(BaseResolver):
222 """ 242 """
223 Class used to resolve from a set or frozenset. 243 Class used to resolve from a set or frozenset.
224 """ 244 """
225 def resolve(self, var, attribute): 245 def resolve(self, var, attribute):
234 @rtype any 254 @rtype any
235 """ 255 """
236 if attribute in ('___len___', TooLargeAttribute): 256 if attribute in ('___len___', TooLargeAttribute):
237 return None 257 return None
238 258
239 if attribute.startswith("ID:"): 259 if attribute.startswith("ID: "):
240 attribute = attribute.split(None, 1)[1] 260 attribute = attribute.split(None, 1)[1]
241 try: 261 try:
242 attribute = int(attribute) 262 attribute = int(attribute)
243 except Exception: 263 except Exception:
244 return getattr(var, attribute) 264 return getattr(var, attribute, None)
245 265
246 for v in var: 266 for v in var:
247 if id(v) == attribute: 267 if id(v) == attribute:
248 return v 268 return v
249 269
274 d.update(additionals) 294 d.update(additionals)
275 295
276 return d 296 return d
277 297
278 298
299 ############################################################
300 ## Resolver for Numpy Arrays
301 ############################################################
302
303
304 class NdArrayResolver(BaseResolver):
305 """
306 Class used to resolve from numpy ndarray including some meta data.
307 """
308 def __isNumeric(self, arr):
309 """
310 Private method to check, if an array is of a numeric type.
311
312 @param arr array to check
313 @type ndarray
314 @return flag indicating a numeric array
315 @rtype bool
316 """
317 try:
318 return arr.dtype.kind in 'biufc'
319 except AttributeError:
320 return False
321
322 def resolve(self, var, attribute):
323 """
324 Public method to get an attribute from a variable.
325
326 @param var variable to extract an attribute or value from
327 @type tuple or list
328 @param attribute id of the value to extract
329 @type str
330 @return value of the attribute
331 @rtype any
332 """
333 if attribute == '__internals__':
334 return defaultResolver.getDictionary(var)
335
336 if attribute == 'min':
337 if self.__isNumeric(var):
338 return var.min()
339 else:
340 return None
341
342 if attribute == 'max':
343 if self.__isNumeric(var):
344 return var.max()
345 else:
346 return None
347
348 if attribute == 'mean':
349 if self.__isNumeric(var):
350 return var.mean()
351 else:
352 return None
353
354 if attribute == 'shape':
355 return var.shape
356
357 if attribute == 'dtype':
358 return var.dtype
359
360 if attribute == 'size':
361 return var.size
362
363 if attribute.startswith('['):
364 container = NdArrayItemsContainer()
365 count = 0
366 for element in var:
367 setattr(container, str(count), element)
368 count += 1
369 if count > MaxItemsToHandle:
370 setattr(container, TooLargeAttribute, TooLargeMessage)
371 break
372 return container
373
374 return None
375
376 def getDictionary(self, var):
377 """
378 Public method to get the attributes of a variable as a dictionary.
379
380 @param var variable to be converted
381 @type any
382 @return dictionary containing the variable attributes
383 @rtype dict
384 """
385 d = {}
386 d['__internals__'] = defaultResolver.getDictionary(var)
387 if var.size > 1024 * 1024:
388 d['min'] = 'ndarray too big, calculating min would slow down' \
389 ' debugging'
390 d['max'] = 'ndarray too big, calculating max would slow down' \
391 ' debugging'
392 else:
393 if self.__isNumeric(var):
394 d['min'] = var.min()
395 d['max'] = var.max()
396 d['mean'] = var.mean()
397 else:
398 d['min'] = 'not a numeric object'
399 d['max'] = 'not a numeric object'
400 d['mean'] = 'not a numeric object'
401 d['shape'] = var.shape
402 d['dtype'] = var.dtype
403 d['size'] = var.size
404 d['[0:{0}]'.format(len(var) - 1)] = list(var[0:MaxItemsToHandle])
405 return d
406
407
408 class NdArrayItemsContainer:
409 """
410 Class to store ndarray items.
411 """
412 pass
413
414
415 ############################################################
416 ## Resolver for Django Multi Value Dictionaries
417 ############################################################
418
419
420 class MultiValueDictResolver(DictResolver):
421 """
422 Class used to resolve from Django multi value dictionaries.
423 """
424 def resolve(self, var, attribute):
425 """
426 Public method to get an attribute from a variable.
427
428 @param var variable to extract an attribute or value from
429 @type dict
430 @param attribute name of the attribute to extract
431 @type str
432 @return value of the attribute
433 @rtype any
434 """
435 if attribute in ('___len___', TooLargeAttribute):
436 return None
437
438 if "(ID:" not in attribute:
439 try:
440 return var[attribute]
441 except Exception:
442 return getattr(var, attribute, None)
443
444 expectedID = int(attribute.split("(ID:")[-1][:-1])
445 for key in var.keys():
446 if id(key) == expectedID:
447 value = var.getlist(key)
448 return value
449
450 return None
451
452 def getDictionary(self, var):
453 """
454 Public method to get the attributes of a variable as a dictionary.
455
456 @param var variable to be converted
457 @type any
458 @return dictionary containing the variable attributes
459 @rtype dict
460 """
461 d = {}
462 count = 0
463 for key in var.keys():
464 count += 1
465 value = var.getlist(key)
466 key = "{0} (ID:{1})".format(self.keyToStr(key), id(key))
467 d[key] = value
468 if count > MaxItemsToHandle:
469 d[TooLargeAttribute] = TooLargeMessage
470 break
471
472 d["___len___"] = len(var)
473
474 return d
475
476
477 ############################################################
478 ## Resolver for array.array
479 ############################################################
480
481
482 class ArrayResolver(BaseResolver):
483 """
484 Class used to resolve from array.array including some meta data.
485 """
486 TypeCodeMap = {
487 "b": "int (signed char)",
488 "B": "int (unsigned char)",
489 "u": "Unicode character (Py_UNICODE)",
490 "h": "int (signed short)",
491 "H": "int (unsigned short)",
492 "i": "int (signed int)",
493 "I": "int (unsigned int)",
494 "l": "int (signed long)",
495 "L": "int (unsigned long)",
496 "q": "int (signed long long)",
497 "Q": "int (unsigned long long)",
498 "f": "float (float)",
499 "d": "float (double)",
500 }
501 def resolve(self, var, attribute):
502 """
503 Public method to get an attribute from a variable.
504
505 @param var variable to extract an attribute or value from
506 @type tuple or list
507 @param attribute id of the value to extract
508 @type str
509 @return value of the attribute
510 @rtype any
511 """
512 if attribute == 'itemsize':
513 return var.itemsize
514
515 if attribute == 'typecode':
516 return var.typecode
517
518 if attribute == 'type':
519 if var.typecode in ArrayResolver.TypeCodeMap:
520 return ArrayResolver.TypeCodeMap[var.typecode]
521 else:
522 return 'illegal type'
523
524 if attribute.startswith('['):
525 container = ArrayItemsContainer()
526 count = 0
527 for element in var:
528 setattr(container, str(count), element)
529 count += 1
530 if count > MaxItemsToHandle:
531 setattr(container, TooLargeAttribute, TooLargeMessage)
532 break
533 return container
534
535 return None
536
537 def getDictionary(self, var):
538 """
539 Public method to get the attributes of a variable as a dictionary.
540
541 @param var variable to be converted
542 @type any
543 @return dictionary containing the variable attributes
544 @rtype dict
545 """
546 d = {}
547 d['typecode'] = var.typecode
548 if var.typecode in ArrayResolver.TypeCodeMap:
549 d['type'] = ArrayResolver.TypeCodeMap[var.typecode]
550 else:
551 d['type'] = 'illegal type'
552 d['itemsize'] = var.itemsize
553 d['[0:{0}]'.format(len(var) - 1)] = var.tolist()[0:MaxItemsToHandle]
554 return d
555
556
557 class ArrayItemsContainer:
558 """
559 Class to store array.array items.
560 """
561 pass
562
563
279 defaultResolver = DefaultResolver() 564 defaultResolver = DefaultResolver()
280 dictResolver = DictResolver() 565 dictResolver = DictResolver()
281 listResolver = ListResolver() 566 listResolver = ListResolver()
282 setResolver = SetResolver() 567 setResolver = SetResolver()
283 568 ndarrayResolver = NdArrayResolver()
284 # TODO: add resolver for numpy arrays 569 multiValueDictResolver = MultiValueDictResolver()
285 # TODO: add resolver for Django MultiValueDict 570 arrayResolver = ArrayResolver()
286 # TODO: add resolver for collections.deque
287 571
288 ############################################################ 572 ############################################################
289 ## Methods to determine the type of a variable and the 573 ## Methods to determine the type of a variable and the
290 ## resolver class to use 574 ## resolver class to use
291 ############################################################ 575 ############################################################
327 611
328 try: 612 try:
329 _TypeMap.append((frozenset, setResolver)) # __IGNORE_WARNING__ 613 _TypeMap.append((frozenset, setResolver)) # __IGNORE_WARNING__
330 except Exception: 614 except Exception:
331 pass # not available on all python versions 615 pass # not available on all python versions
616
617 try:
618 import array
619 _TypeMap.append((array.array, arrayResolver))
620 except ImportError:
621 pass # array.array may not be available
622
623 try:
624 import numpy
625 _TypeMap.append((numpy.ndarray, ndarrayResolver))
626 except ImportError:
627 pass # numpy may not be installed
628
629 try:
630 from django.utils.datastructures import MultiValueDict
631 _TypeMap.insert(0, (MultiValueDict, multiValueDictResolver))
632 # it should go before dict
633 except ImportError:
634 pass # django may not be installed
332 635
333 636
334 def getType(obj): 637 def getType(obj):
335 """ 638 """
336 Public method to get the type information for an object. 639 Public method to get the type information for an object.

eric ide

mercurial