5 |
5 |
6 """ |
6 """ |
7 Module implementing classes and functions to dump variable contents. |
7 Module implementing classes and functions to dump variable contents. |
8 """ |
8 """ |
9 |
9 |
|
10 import sys |
|
11 |
|
12 from DebugConfig import ConfigQtNames, BatchSize |
|
13 |
10 # |
14 # |
11 # This code was inspired by pydevd. |
15 # This code was inspired by pydevd. |
12 # |
16 # |
13 |
17 |
14 MaxItemsToHandle = 300 |
18 if sys.version_info[0] > 2: |
15 TooLargeMessage = ("Too large to show contents. Max items to show: " + |
19 basestring = str |
16 str(MaxItemsToHandle)) |
|
17 TooLargeAttribute = "Too large to be handled." |
|
18 |
20 |
19 ############################################################ |
21 ############################################################ |
20 ## Classes implementing resolvers for various compund types |
22 ## Classes implementing resolvers for various compund types |
21 ############################################################ |
23 ############################################################ |
22 |
24 |
23 |
25 |
24 class BaseResolver(object): |
26 class BaseResolver(object): |
25 """ |
27 """ |
26 Base class of the resolver class tree. |
28 Base class of the resolver class tree. |
27 """ |
|
28 def resolve(self, var, attribute): |
|
29 """ |
|
30 Public method to get an attribute from a variable. |
|
31 |
|
32 @param var variable to extract an attribute or value from |
|
33 @type any |
|
34 @param attribute name of the attribute to extract |
|
35 @type str |
|
36 @return value of the attribute |
|
37 @rtype any |
|
38 @exception NotImplementedError raised to indicate a missing |
|
39 implementation |
|
40 """ # __IGNORE_WARNING_D235__ |
|
41 raise NotImplementedError |
|
42 |
|
43 def getDictionary(self, var): |
|
44 """ |
|
45 Public method to get the attributes of a variable as a dictionary. |
|
46 |
|
47 @param var variable to be converted |
|
48 @type any |
|
49 @return dictionary containing the variable attributes |
|
50 @rtype dict |
|
51 @exception NotImplementedError raised to indicate a missing |
|
52 implementation |
|
53 """ # __IGNORE_WARNING_D235__ |
|
54 raise NotImplementedError |
|
55 |
|
56 |
|
57 ############################################################ |
|
58 ## Default Resolver |
|
59 ############################################################ |
|
60 |
|
61 |
|
62 class DefaultResolver(BaseResolver): |
|
63 """ |
|
64 Class used to resolve the default way. |
|
65 """ |
29 """ |
66 def resolve(self, var, attribute): |
30 def resolve(self, var, attribute): |
67 """ |
31 """ |
68 Public method to get an attribute from a variable. |
32 Public method to get an attribute from a variable. |
69 |
33 |
99 |
63 |
100 return d |
64 return d |
101 |
65 |
102 |
66 |
103 ############################################################ |
67 ############################################################ |
|
68 ## Default Resolver |
|
69 ############################################################ |
|
70 |
|
71 |
|
72 class DefaultResolver(BaseResolver): |
|
73 """ |
|
74 Class used to resolve the default way. |
|
75 """ |
|
76 def getDictionary(self, var): |
|
77 """ |
|
78 Public method to get the attributes of a variable as a dictionary. |
|
79 |
|
80 @param var variable to be converted |
|
81 @type any |
|
82 @return dictionary containing the variable attributes |
|
83 @rtype dict |
|
84 """ |
|
85 names = dir(var) |
|
86 if not names and hasattr(var, "__members__"): |
|
87 names = var.__members__ |
|
88 |
|
89 d = {} |
|
90 for name in names: |
|
91 try: |
|
92 attribute = getattr(var, name) |
|
93 d[name] = attribute |
|
94 except Exception: |
|
95 pass # if we can't get it, simply ignore it |
|
96 |
|
97 yield -1, d |
|
98 while True: |
|
99 yield -2, {} |
|
100 |
|
101 |
|
102 ############################################################ |
104 ## Resolver for Dictionaries |
103 ## Resolver for Dictionaries |
105 ############################################################ |
104 ############################################################ |
106 |
105 |
107 |
106 |
108 class DictResolver(BaseResolver): |
107 class DictResolver(BaseResolver): |
118 @param attribute name of the attribute to extract |
117 @param attribute name of the attribute to extract |
119 @type str |
118 @type str |
120 @return value of the attribute |
119 @return value of the attribute |
121 @rtype any |
120 @rtype any |
122 """ |
121 """ |
123 if attribute in ('___len___', TooLargeAttribute): |
122 if " (ID:" not in attribute: |
124 return None |
|
125 |
|
126 if "(ID:" not in attribute: |
|
127 try: |
123 try: |
128 return var[attribute] |
124 return var[attribute] |
129 except Exception: |
125 except Exception: |
130 return getattr(var, attribute, None) |
126 return getattr(var, attribute, None) |
131 |
127 |
132 expectedID = int(attribute.split("(ID:")[-1][:-1]) |
128 expectedID = int(attribute.split(" (ID:")[-1][:-1]) |
133 for key, value in var.items(): |
129 for key, value in var.items(): |
134 if id(key) == expectedID: |
130 if id(key) == expectedID: |
135 return value |
131 return value |
136 |
132 |
137 return None |
133 return None |
143 @param key key to be converted |
139 @param key key to be converted |
144 @type any |
140 @type any |
145 @return string representation of the given key |
141 @return string representation of the given key |
146 @rtype str |
142 @rtype str |
147 """ |
143 """ |
148 if isinstance(key, str): |
144 if isinstance(key, basestring): |
149 return repr(key) |
145 key = repr(key) |
150 else: |
146 # Special handling for Python2 unicode strings and bytes object |
151 return key |
147 # Raw and f-Strings are always converted to (unicode) str |
152 |
148 if key[0] in 'ub': |
153 def getDictionary(self, var): |
149 key = key[1:] |
154 """ |
150 |
155 Public method to get the attributes of a variable as a dictionary. |
151 return key # __IGNORE_WARNING_M834__ |
156 |
152 |
157 @param var variable to be converted |
153 def getDictionary(self, var): |
158 @type any |
154 """ |
159 @return dictionary containing the variable attributes |
155 Public method to get the attributes of a variable as a dictionary. |
160 @rtype dict |
156 |
161 """ |
157 @param var variable to be converted |
162 d = {} |
158 @type any |
163 count = 0 |
159 @return dictionary containing the variable attributes |
164 for key, value in var.items(): |
160 @rtype dict |
165 count += 1 |
161 """ |
|
162 d = {} |
|
163 start = count = 0 |
|
164 allItems = list(var.items()) |
|
165 try: |
|
166 # Fast path: all items from same type |
|
167 allItems.sort(key=lambda x: x[0]) |
|
168 except TypeError: |
|
169 # Slow path: only sort items with same type (Py3 only) |
|
170 allItems.sort(key=lambda x: (str(x[0]), x[0])) |
|
171 |
|
172 for key, value in allItems: |
166 key = "{0} (ID:{1})".format(self.keyToStr(key), id(key)) |
173 key = "{0} (ID:{1})".format(self.keyToStr(key), id(key)) |
167 d[key] = value |
174 d[key] = value |
168 if count > MaxItemsToHandle: |
175 count += 1 |
169 d[TooLargeAttribute] = TooLargeMessage |
176 if count >= BatchSize: |
170 break |
177 yield start, d |
171 |
178 start += count |
172 d["___len___"] = len(var) |
179 count = 0 |
|
180 d = {} |
|
181 |
|
182 if d: |
|
183 yield start, d |
173 |
184 |
174 # in case it has additional fields |
185 # in case it has additional fields |
175 additionals = defaultResolver.getDictionary(var) |
186 d = super(DictResolver, self).getDictionary(var) |
176 d.update(additionals) |
187 yield -1, d |
177 |
188 |
178 return d |
189 while True: |
|
190 yield -2, {} |
179 |
191 |
180 |
192 |
181 ############################################################ |
193 ############################################################ |
182 ## Resolver for Lists and Tuples |
194 ## Resolver for Lists and Tuples |
183 ############################################################ |
195 ############################################################ |
196 @param attribute name of the attribute to extract |
208 @param attribute name of the attribute to extract |
197 @type str |
209 @type str |
198 @return value of the attribute |
210 @return value of the attribute |
199 @rtype any |
211 @rtype any |
200 """ |
212 """ |
201 if attribute in ('___len___', TooLargeAttribute): |
|
202 return None |
|
203 |
|
204 try: |
213 try: |
205 return var[int(attribute)] |
214 return var[int(attribute)] |
206 except Exception: |
215 except Exception: |
207 return getattr(var, attribute, None) |
216 return getattr(var, attribute, None) |
208 |
217 |
214 @type any |
223 @type any |
215 @return dictionary containing the variable attributes |
224 @return dictionary containing the variable attributes |
216 @rtype dict |
225 @rtype dict |
217 """ |
226 """ |
218 d = {} |
227 d = {} |
219 count = 0 |
228 start = count = 0 |
220 for value in var: |
229 for idx, value in enumerate(var): |
221 d[str(count)] = value |
230 d[str(idx)] = value |
222 count += 1 |
231 count += 1 |
223 if count > MaxItemsToHandle: |
232 if count >= BatchSize: |
224 d[TooLargeAttribute] = TooLargeMessage |
233 yield start, d |
225 break |
234 start = idx + 1 |
226 |
235 count = 0 |
227 d["___len___"] = len(var) |
236 d = {} |
|
237 |
|
238 if d: |
|
239 yield start, d |
228 |
240 |
229 # in case it has additional fields |
241 # in case it has additional fields |
230 additionals = defaultResolver.getDictionary(var) |
242 d = super(ListResolver, self).getDictionary(var) |
231 d.update(additionals) |
243 yield -1, d |
232 |
244 |
233 return d |
245 while True: |
234 |
246 yield -2, {} |
|
247 |
235 |
248 |
236 ############################################################ |
249 ############################################################ |
237 ## Resolver for Sets and Frozensets |
250 ## Resolver for Sets and Frozensets |
238 ############################################################ |
251 ############################################################ |
239 |
252 |
251 @param attribute id of the value to extract |
264 @param attribute id of the value to extract |
252 @type str |
265 @type str |
253 @return value of the attribute |
266 @return value of the attribute |
254 @rtype any |
267 @rtype any |
255 """ |
268 """ |
256 if attribute in ('___len___', TooLargeAttribute): |
269 if attribute.startswith("'ID: "): |
257 return None |
270 attribute = attribute.split(None, 1)[1][:-1] |
258 |
|
259 if attribute.startswith("ID: "): |
|
260 attribute = attribute.split(None, 1)[1] |
|
261 try: |
271 try: |
262 attribute = int(attribute) |
272 attribute = int(attribute) |
263 except Exception: |
273 except Exception: |
264 return getattr(var, attribute, None) |
274 return getattr(var, attribute, None) |
265 |
275 |
277 @type any |
287 @type any |
278 @return dictionary containing the variable attributes |
288 @return dictionary containing the variable attributes |
279 @rtype dict |
289 @rtype dict |
280 """ |
290 """ |
281 d = {} |
291 d = {} |
282 count = 0 |
292 start = count = 0 |
283 for value in var: |
293 for value in var: |
284 count += 1 |
294 count += 1 |
285 d["ID: " + str(id(value))] = value |
295 d["'ID: {0}'".format(id(value))] = value |
286 if count > MaxItemsToHandle: |
296 if count >= BatchSize: |
287 d[TooLargeAttribute] = TooLargeMessage |
297 yield start, d |
288 break |
298 start += count |
289 |
299 count = 0 |
290 d["___len___"] = len(var) |
300 d = {} |
|
301 |
|
302 if d: |
|
303 yield start, d |
291 |
304 |
292 # in case it has additional fields |
305 # in case it has additional fields |
293 additionals = defaultResolver.getDictionary(var) |
306 additionals = super(SetResolver, self).getDictionary(var) |
294 d.update(additionals) |
307 yield -1, additionals |
295 |
308 |
296 return d |
309 while True: |
297 |
310 yield -2, {} |
|
311 |
298 |
312 |
299 ############################################################ |
313 ############################################################ |
300 ## Resolver for Numpy Arrays |
314 ## Resolver for Numpy Arrays |
301 ############################################################ |
315 ############################################################ |
302 |
316 |
349 if self.__isNumeric(var): |
360 if self.__isNumeric(var): |
350 return var.mean() |
361 return var.mean() |
351 else: |
362 else: |
352 return None |
363 return None |
353 |
364 |
354 if attribute == 'shape': |
365 try: |
355 return var.shape |
366 return var[int(attribute)] |
356 |
367 except Exception: |
357 if attribute == 'dtype': |
368 return getattr(var, attribute, None) |
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 |
369 |
374 return None |
370 return None |
375 |
371 |
376 def getDictionary(self, var): |
372 def getDictionary(self, var): |
377 """ |
373 """ |
381 @type any |
377 @type any |
382 @return dictionary containing the variable attributes |
378 @return dictionary containing the variable attributes |
383 @rtype dict |
379 @rtype dict |
384 """ |
380 """ |
385 d = {} |
381 d = {} |
386 d['__internals__'] = defaultResolver.getDictionary(var) |
382 start = count = 0 |
|
383 allItems = var.tolist() |
|
384 |
|
385 for idx, value in enumerate(allItems): |
|
386 d[str(idx)] = value |
|
387 count += 1 |
|
388 if count >= BatchSize: |
|
389 yield start, d |
|
390 start += count |
|
391 count = 0 |
|
392 d = {} |
|
393 |
|
394 if d: |
|
395 yield start, d |
|
396 |
|
397 # in case it has additional fields |
|
398 d = super(NdArrayResolver, self).getDictionary(var) |
|
399 |
387 if var.size > 1024 * 1024: |
400 if var.size > 1024 * 1024: |
388 d['min'] = 'ndarray too big, calculating min would slow down' \ |
401 d['min'] = 'ndarray too big, calculating min would slow down' \ |
389 ' debugging' |
402 ' debugging' |
390 d['max'] = 'ndarray too big, calculating max would slow down' \ |
403 d['max'] = 'ndarray too big, calculating max would slow down' \ |
391 ' debugging' |
404 ' debugging' |
|
405 d['mean'] = 'ndarray too big, calculating mean would slow down' \ |
|
406 ' debugging' |
|
407 elif self.__isNumeric(var): |
|
408 if var.size == 0: |
|
409 d['min'] = 'empty array' |
|
410 d['max'] = 'empty array' |
|
411 d['mean'] = 'empty array' |
|
412 else: |
|
413 d['min'] = var.min() |
|
414 d['max'] = var.max() |
|
415 d['mean'] = var.mean() |
392 else: |
416 else: |
393 if self.__isNumeric(var): |
417 d['min'] = 'not a numeric object' |
394 if var.size == 0: |
418 d['max'] = 'not a numeric object' |
395 d['min'] = 'empty array' |
419 d['mean'] = 'not a numeric object' |
396 d['max'] = 'empty array' |
420 |
397 d['mean'] = 'empty array' |
421 yield -1, d |
398 else: |
422 |
399 d['min'] = var.min() |
423 while True: |
400 d['max'] = var.max() |
424 yield -2, {} |
401 d['mean'] = var.mean() |
|
402 else: |
|
403 d['min'] = 'not a numeric object' |
|
404 d['max'] = 'not a numeric object' |
|
405 d['mean'] = 'not a numeric object' |
|
406 d['shape'] = var.shape |
|
407 d['dtype'] = var.dtype |
|
408 d['size'] = var.size |
|
409 d['[0:{0}]'.format(len(var) - 1)] = list(var[0:MaxItemsToHandle]) |
|
410 return d |
|
411 |
|
412 |
|
413 class NdArrayItemsContainer: |
|
414 """ |
|
415 Class to store ndarray items. |
|
416 """ |
|
417 pass |
|
418 |
425 |
419 |
426 |
420 ############################################################ |
427 ############################################################ |
421 ## Resolver for Django Multi Value Dictionaries |
428 ## Resolver for Django Multi Value Dictionaries |
422 ############################################################ |
429 ############################################################ |
435 @param attribute name of the attribute to extract |
442 @param attribute name of the attribute to extract |
436 @type str |
443 @type str |
437 @return value of the attribute |
444 @return value of the attribute |
438 @rtype any |
445 @rtype any |
439 """ |
446 """ |
440 if attribute in ('___len___', TooLargeAttribute): |
447 if " (ID:" not in attribute: |
441 return None |
|
442 |
|
443 if "(ID:" not in attribute: |
|
444 try: |
448 try: |
445 return var[attribute] |
449 return var[attribute] |
446 except Exception: |
450 except Exception: |
447 return getattr(var, attribute, None) |
451 return getattr(var, attribute, None) |
448 |
452 |
449 expectedID = int(attribute.split("(ID:")[-1][:-1]) |
453 expectedID = int(attribute.split(" (ID:")[-1][:-1]) |
450 for key in var.keys(): |
454 for key in var.keys(): |
451 if id(key) == expectedID: |
455 if id(key) == expectedID: |
452 value = var.getlist(key) |
456 return var.getlist(key) |
453 return value |
|
454 |
457 |
455 return None |
458 return None |
456 |
459 |
457 def getDictionary(self, var): |
460 def getDictionary(self, var): |
458 """ |
461 """ |
462 @type any |
465 @type any |
463 @return dictionary containing the variable attributes |
466 @return dictionary containing the variable attributes |
464 @rtype dict |
467 @rtype dict |
465 """ |
468 """ |
466 d = {} |
469 d = {} |
467 count = 0 |
470 start = count = 0 |
468 for key in var.keys(): |
471 allKeys = list(var.keys()) |
|
472 try: |
|
473 # Fast path: all items from same type |
|
474 allKeys.sort() |
|
475 except TypeError: |
|
476 # Slow path: only sort items with same type (Py3 only) |
|
477 allKeys.sort(key=lambda x: (str(x), x)) |
|
478 |
|
479 for key in allKeys: |
|
480 dkey = "{0} (ID:{1})".format(self.keyToStr(key), id(key)) |
|
481 d[dkey] = var.getlist(key) |
469 count += 1 |
482 count += 1 |
470 value = var.getlist(key) |
483 if count >= BatchSize: |
471 key = "{0} (ID:{1})".format(self.keyToStr(key), id(key)) |
484 yield start, d |
472 d[key] = value |
485 start += count |
473 if count > MaxItemsToHandle: |
486 count = 0 |
474 d[TooLargeAttribute] = TooLargeMessage |
487 d = {} |
475 break |
488 |
476 |
489 if d: |
477 d["___len___"] = len(var) |
490 yield start, d |
478 |
491 |
479 return d |
492 # in case it has additional fields |
480 |
493 d = super(DictResolver, self).getDictionary(var) |
|
494 yield -1, d |
|
495 |
|
496 while True: |
|
497 yield -2, {} |
|
498 |
481 |
499 |
482 ############################################################ |
500 ############################################################ |
483 ## Resolver for array.array |
501 ## Resolver for array.array |
484 ############################################################ |
502 ############################################################ |
485 |
503 |
513 @param attribute id of the value to extract |
531 @param attribute id of the value to extract |
514 @type str |
532 @type str |
515 @return value of the attribute |
533 @return value of the attribute |
516 @rtype any |
534 @rtype any |
517 """ |
535 """ |
518 if attribute == 'itemsize': |
536 try: |
519 return var.itemsize |
537 return var[int(attribute)] |
520 |
538 except Exception: |
521 if attribute == 'typecode': |
539 return getattr(var, attribute, None) |
522 return var.typecode |
|
523 |
|
524 if attribute == 'type': |
|
525 if var.typecode in ArrayResolver.TypeCodeMap: |
|
526 return ArrayResolver.TypeCodeMap[var.typecode] |
|
527 else: |
|
528 return 'illegal type' |
|
529 |
|
530 if attribute.startswith('['): |
|
531 container = ArrayItemsContainer() |
|
532 count = 0 |
|
533 for element in var: |
|
534 setattr(container, str(count), element) |
|
535 count += 1 |
|
536 if count > MaxItemsToHandle: |
|
537 setattr(container, TooLargeAttribute, TooLargeMessage) |
|
538 break |
|
539 return container |
|
540 |
540 |
541 return None |
541 return None |
542 |
542 |
543 def getDictionary(self, var): |
543 def getDictionary(self, var): |
544 """ |
544 """ |
548 @type any |
548 @type any |
549 @return dictionary containing the variable attributes |
549 @return dictionary containing the variable attributes |
550 @rtype dict |
550 @rtype dict |
551 """ |
551 """ |
552 d = {} |
552 d = {} |
553 d['typecode'] = var.typecode |
553 start = count = 0 |
554 if var.typecode in ArrayResolver.TypeCodeMap: |
554 allItems = var.tolist() |
555 d['type'] = ArrayResolver.TypeCodeMap[var.typecode] |
555 |
556 else: |
556 for idx, value in enumerate(allItems): |
557 d['type'] = 'illegal type' |
557 d[str(idx)] = value |
558 d['itemsize'] = var.itemsize |
558 count += 1 |
559 d['[0:{0}]'.format(len(var) - 1)] = var.tolist()[0:MaxItemsToHandle] |
559 if count >= BatchSize: |
560 return d |
560 yield start, d |
561 |
561 start += count |
562 |
562 count = 0 |
563 class ArrayItemsContainer: |
563 d = {} |
564 """ |
564 |
565 Class to store array.array items. |
565 if d: |
566 """ |
566 yield start, d |
567 pass |
567 |
|
568 # in case it has additional fields |
|
569 d = super(ArrayResolver, self).getDictionary(var) |
|
570 |
|
571 # Special data for array type: convert typecode to readable text |
|
572 d['type'] = self.TypeCodeMap.get(var.typecode, 'illegal type') |
|
573 |
|
574 yield -1, d |
|
575 |
|
576 while True: |
|
577 yield -2, {} |
568 |
578 |
569 |
579 |
570 defaultResolver = DefaultResolver() |
580 defaultResolver = DefaultResolver() |
571 dictResolver = DictResolver() |
581 dictResolver = DictResolver() |
572 listResolver = ListResolver() |
582 listResolver = ListResolver() |
596 (complex, None), |
606 (complex, None), |
597 (str, None), |
607 (str, None), |
598 (tuple, listResolver), |
608 (tuple, listResolver), |
599 (list, listResolver), |
609 (list, listResolver), |
600 (dict, dictResolver), |
610 (dict, dictResolver), |
|
611 (set, setResolver), |
|
612 (frozenset, setResolver), |
601 ] |
613 ] |
602 |
614 |
603 try: |
615 try: |
604 _TypeMap.append((long, None)) # __IGNORE_WARNING__ |
616 _TypeMap.append((long, None)) # __IGNORE_WARNING__ |
605 except Exception: |
617 except Exception: |
608 try: |
620 try: |
609 _TypeMap.append((unicode, None)) # __IGNORE_WARNING__ |
621 _TypeMap.append((unicode, None)) # __IGNORE_WARNING__ |
610 except Exception: |
622 except Exception: |
611 pass # not available on all python versions |
623 pass # not available on all python versions |
612 |
624 |
613 try: |
|
614 _TypeMap.append((set, setResolver)) # __IGNORE_WARNING__ |
|
615 except Exception: |
|
616 pass # not available on all python versions |
|
617 |
|
618 try: |
|
619 _TypeMap.append((frozenset, setResolver)) # __IGNORE_WARNING__ |
|
620 except Exception: |
|
621 pass # not available on all python versions |
|
622 |
|
623 try: |
625 try: |
624 import array |
626 import array |
625 _TypeMap.append((array.array, arrayResolver)) |
627 _TypeMap.append((array.array, arrayResolver)) |
626 except ImportError: |
628 except ImportError: |
627 pass # array.array may not be available |
629 pass # array.array may not be available |
632 except ImportError: |
634 except ImportError: |
633 pass # numpy may not be installed |
635 pass # numpy may not be installed |
634 |
636 |
635 try: |
637 try: |
636 from django.utils.datastructures import MultiValueDict |
638 from django.utils.datastructures import MultiValueDict |
|
639 # it should go before dict |
637 _TypeMap.insert(0, (MultiValueDict, multiValueDictResolver)) |
640 _TypeMap.insert(0, (MultiValueDict, multiValueDictResolver)) |
638 # it should go before dict |
|
639 except ImportError: |
641 except ImportError: |
640 pass # django may not be installed |
642 pass # django may not be installed |
641 |
643 |
642 |
644 |
643 def getType(obj): |
645 def getType(obj): |
644 """ |
646 """ |
645 Public method to get the type information for an object. |
647 Public method to get the type information for an object. |
646 |
648 |
647 @param obj object to get type information for |
649 @param obj object to get type information for |
648 @type any |
650 @type any |
649 @return tuple containing the type, type name, type string and resolver |
651 @return tuple containing the type name, type string and resolver |
650 @rtype tuple of type, str, str, BaseResolver |
652 @rtype tuple of str, str, BaseResolver |
651 """ |
653 """ |
652 typeObject = type(obj) |
654 typeObject = type(obj) |
653 typeName = typeObject.__name__ |
655 typeName = typeObject.__name__ |
654 typeStr = str(typeObject)[8:-2] |
656 # Between PyQt and PySide the returned type is different (class vs. type) |
655 |
657 typeStr = str(typeObject).split(' ', 1)[-1] |
656 if typeStr.startswith(("PyQt5.", "PyQt4.")): |
658 typeStr = typeStr[1:-2] |
|
659 |
|
660 if typeStr.startswith(ConfigQtNames): |
657 resolver = None |
661 resolver = None |
658 else: |
662 else: |
659 if _TypeMap is None: |
663 if _TypeMap is None: |
660 _initTypeMap() |
664 _initTypeMap() |
661 |
665 |
662 for typeData in _TypeMap: |
666 for typeData, resolver in _TypeMap: # __IGNORE_WARNING_M507__ |
663 if isinstance(obj, typeData[0]): |
667 if isinstance(obj, typeData): |
664 resolver = typeData[1] |
|
665 break |
668 break |
666 else: |
669 else: |
667 resolver = defaultResolver |
670 resolver = defaultResolver |
668 |
671 |
669 return typeObject, typeName, typeStr, resolver |
672 return typeName, typeStr, resolver |
670 |
673 |
671 # |
674 # |
672 # eflag: noqa = M702 |
675 # eflag: noqa = M702 |