src/eric7/DebugClients/Python/DebugVariables.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9462
e65379fdbd97
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
25 25
26 class BaseResolver: 26 class BaseResolver:
27 """ 27 """
28 Base class of the resolver class tree. 28 Base class of the resolver class tree.
29 """ 29 """
30
30 def resolve(self, var, attribute): 31 def resolve(self, var, attribute):
31 """ 32 """
32 Public method to get an attribute from a variable. 33 Public method to get an attribute from a variable.
33 34
34 @param var variable to extract an attribute or value from 35 @param var variable to extract an attribute or value from
35 @type any 36 @type any
36 @param attribute name of the attribute to extract 37 @param attribute name of the attribute to extract
37 @type str 38 @type str
38 @return value of the attribute 39 @return value of the attribute
39 @rtype any 40 @rtype any
40 """ 41 """
41 return getattr(var, attribute, None) 42 return getattr(var, attribute, None)
42 43
43 def getVariableList(self, var): 44 def getVariableList(self, var):
44 """ 45 """
45 Public method to get the attributes of a variable as a list. 46 Public method to get the attributes of a variable as a list.
46 47
47 @param var variable to be converted 48 @param var variable to be converted
48 @type any 49 @type any
49 @return list containing the variable attributes 50 @return list containing the variable attributes
50 @rtype list 51 @rtype list
51 """ 52 """
52 d = [] 53 d = []
53 for name in dir(var): 54 for name in dir(var):
54 with contextlib.suppress(Exception): 55 with contextlib.suppress(Exception):
55 attribute = getattr(var, name) 56 attribute = getattr(var, name)
56 d.append((name, attribute)) 57 d.append((name, attribute))
57 58
58 return d 59 return d
59 60
60 61
61 ############################################################ 62 ############################################################
62 ## Default Resolver 63 ## Default Resolver
65 66
66 class DefaultResolver(BaseResolver): 67 class DefaultResolver(BaseResolver):
67 """ 68 """
68 Class used to resolve the default way. 69 Class used to resolve the default way.
69 """ 70 """
70 def getVariableList(self, var): 71
71 """ 72 def getVariableList(self, var):
72 Public method to get the attributes of a variable as a list. 73 """
73 74 Public method to get the attributes of a variable as a list.
75
74 @param var variable to be converted 76 @param var variable to be converted
75 @type any 77 @type any
76 @yield tuple containing the batch start index and a list 78 @yield tuple containing the batch start index and a list
77 containing the variable attributes 79 containing the variable attributes
78 @ytype tuple of (int, list) 80 @ytype tuple of (int, list)
80 d = [] 82 d = []
81 for name in dir(var): 83 for name in dir(var):
82 with contextlib.suppress(Exception): 84 with contextlib.suppress(Exception):
83 attribute = getattr(var, name) 85 attribute = getattr(var, name)
84 d.append((name, attribute)) 86 d.append((name, attribute))
85 87
86 yield -1, d 88 yield -1, d
87 while True: 89 while True:
88 yield -2, [] 90 yield -2, []
89 91
90 92
95 97
96 class DictResolver(BaseResolver): 98 class DictResolver(BaseResolver):
97 """ 99 """
98 Class used to resolve from a dictionary. 100 Class used to resolve from a dictionary.
99 """ 101 """
102
100 def resolve(self, var, attribute): 103 def resolve(self, var, attribute):
101 """ 104 """
102 Public method to get an attribute from a variable. 105 Public method to get an attribute from a variable.
103 106
104 @param var variable to extract an attribute or value from 107 @param var variable to extract an attribute or value from
105 @type dict 108 @type dict
106 @param attribute name of the attribute to extract 109 @param attribute name of the attribute to extract
107 @type str 110 @type str
108 @return value of the attribute 111 @return value of the attribute
111 if " (ID:" not in attribute: 114 if " (ID:" not in attribute:
112 try: 115 try:
113 return var[attribute] 116 return var[attribute]
114 except Exception: 117 except Exception:
115 return getattr(var, attribute, None) 118 return getattr(var, attribute, None)
116 119
117 expectedID = int(attribute.split(" (ID:")[-1][:-1]) 120 expectedID = int(attribute.split(" (ID:")[-1][:-1])
118 for key, value in var.items(): 121 for key, value in var.items():
119 if id(key) == expectedID: 122 if id(key) == expectedID:
120 return value 123 return value
121 124
122 return None 125 return None
123 126
124 def keyToStr(self, key): 127 def keyToStr(self, key):
125 """ 128 """
126 Public method to get a string representation for a key. 129 Public method to get a string representation for a key.
127 130
128 @param key key to be converted 131 @param key key to be converted
129 @type any 132 @type any
130 @return string representation of the given key 133 @return string representation of the given key
131 @rtype str 134 @rtype str
132 """ 135 """
133 if isinstance(key, str): 136 if isinstance(key, str):
134 key = repr(key) 137 key = repr(key)
135 # Special handling for bytes object 138 # Special handling for bytes object
136 # Raw and f-Strings are always converted to str 139 # Raw and f-Strings are always converted to str
137 if key[0] == 'b': 140 if key[0] == "b":
138 key = key[1:] 141 key = key[1:]
139 142
140 return key # __IGNORE_WARNING_M834__ 143 return key # __IGNORE_WARNING_M834__
141 144
142 def getVariableList(self, var): 145 def getVariableList(self, var):
143 """ 146 """
144 Public method to get the attributes of a variable as a list. 147 Public method to get the attributes of a variable as a list.
145 148
146 @param var variable to be converted 149 @param var variable to be converted
147 @type any 150 @type any
148 @yield tuple containing the batch start index and a list 151 @yield tuple containing the batch start index and a list
149 containing the variable attributes 152 containing the variable attributes
150 @ytype tuple of (int, list) 153 @ytype tuple of (int, list)
156 # Fast path: all items from same type 159 # Fast path: all items from same type
157 allItems.sort(key=lambda x: x[0]) 160 allItems.sort(key=lambda x: x[0])
158 except TypeError: 161 except TypeError:
159 # Slow path: only sort items with same type (Py3 only) 162 # Slow path: only sort items with same type (Py3 only)
160 allItems.sort(key=lambda x: (str(x[0]), x[0])) 163 allItems.sort(key=lambda x: (str(x[0]), x[0]))
161 164
162 for key, value in allItems: 165 for key, value in allItems:
163 key = "{0} (ID:{1})".format(self.keyToStr(key), id(key)) 166 key = "{0} (ID:{1})".format(self.keyToStr(key), id(key))
164 d.append((key, value)) 167 d.append((key, value))
165 count += 1 168 count += 1
166 if count >= BatchSize: 169 if count >= BatchSize:
167 yield start, d 170 yield start, d
168 start += count 171 start += count
169 count = 0 172 count = 0
170 d = [] 173 d = []
171 174
172 if d: 175 if d:
173 yield start, d 176 yield start, d
174 177
175 # in case it has additional fields 178 # in case it has additional fields
176 d = super().getVariableList(var) 179 d = super().getVariableList(var)
177 yield -1, d 180 yield -1, d
178 181
179 while True: 182 while True:
180 yield -2, [] 183 yield -2, []
181 184
182 185
183 ############################################################ 186 ############################################################
187 190
188 class ListResolver(BaseResolver): 191 class ListResolver(BaseResolver):
189 """ 192 """
190 Class used to resolve from a tuple or list. 193 Class used to resolve from a tuple or list.
191 """ 194 """
195
192 def resolve(self, var, attribute): 196 def resolve(self, var, attribute):
193 """ 197 """
194 Public method to get an attribute from a variable. 198 Public method to get an attribute from a variable.
195 199
196 @param var variable to extract an attribute or value from 200 @param var variable to extract an attribute or value from
197 @type tuple or list 201 @type tuple or list
198 @param attribute name of the attribute to extract 202 @param attribute name of the attribute to extract
199 @type str 203 @type str
200 @return value of the attribute 204 @return value of the attribute
202 """ 206 """
203 try: 207 try:
204 return var[int(attribute)] 208 return var[int(attribute)]
205 except Exception: 209 except Exception:
206 return getattr(var, str(attribute), None) 210 return getattr(var, str(attribute), None)
207 211
208 def getVariableList(self, var): 212 def getVariableList(self, var):
209 """ 213 """
210 Public method to get the attributes of a variable as a list. 214 Public method to get the attributes of a variable as a list.
211 215
212 @param var variable to be converted 216 @param var variable to be converted
213 @type any 217 @type any
214 @yield tuple containing the batch start index and a list 218 @yield tuple containing the batch start index and a list
215 containing the variable attributes 219 containing the variable attributes
216 @ytype tuple of (int, list) 220 @ytype tuple of (int, list)
223 if count >= BatchSize: 227 if count >= BatchSize:
224 yield start, d 228 yield start, d
225 start = idx + 1 229 start = idx + 1
226 count = 0 230 count = 0
227 d = [] 231 d = []
228 232
229 if d: 233 if d:
230 yield start, d 234 yield start, d
231 235
232 # in case it has additional fields 236 # in case it has additional fields
233 d = super().getVariableList(var) 237 d = super().getVariableList(var)
234 yield -1, d 238 yield -1, d
235 239
236 while True: 240 while True:
237 yield -2, [] 241 yield -2, []
238 242
239 243
240 ############################################################ 244 ############################################################
241 ## Resolver for dict_items, dict_keys and dict_values 245 ## Resolver for dict_items, dict_keys and dict_values
242 ############################################################ 246 ############################################################
243 247
244 248
245 class DictViewResolver(ListResolver): 249 class DictViewResolver(ListResolver):
246 """ 250 """
247 Class used to resolve from dict views. 251 Class used to resolve from dict views.
248 """ 252 """
253
249 def resolve(self, var, attribute): 254 def resolve(self, var, attribute):
250 """ 255 """
251 Public method to get an attribute from a variable. 256 Public method to get an attribute from a variable.
252 257
253 @param var variable to extract an attribute or value from 258 @param var variable to extract an attribute or value from
254 @type dict_items, dict_keys or dict_values 259 @type dict_items, dict_keys or dict_values
255 @param attribute id of the value to extract 260 @param attribute id of the value to extract
256 @type str 261 @type str
257 @return value of the attribute 262 @return value of the attribute
258 @rtype any 263 @rtype any
259 """ 264 """
260 return super().resolve(list(var), attribute) 265 return super().resolve(list(var), attribute)
261 266
262 def getVariableList(self, var): 267 def getVariableList(self, var):
263 """ 268 """
264 Public method to get the attributes of a variable as a list. 269 Public method to get the attributes of a variable as a list.
265 270
266 @param var variable to be converted 271 @param var variable to be converted
267 @type any 272 @type any
268 @yield tuple containing the batch start index and a list 273 @yield tuple containing the batch start index and a list
269 containing the variable attributes 274 containing the variable attributes
270 @ytype tuple of (int, list) 275 @ytype tuple of (int, list)
279 284
280 class SetResolver(BaseResolver): 285 class SetResolver(BaseResolver):
281 """ 286 """
282 Class used to resolve from a set or frozenset. 287 Class used to resolve from a set or frozenset.
283 """ 288 """
289
284 def resolve(self, var, attribute): 290 def resolve(self, var, attribute):
285 """ 291 """
286 Public method to get an attribute from a variable. 292 Public method to get an attribute from a variable.
287 293
288 @param var variable to extract an attribute or value from 294 @param var variable to extract an attribute or value from
289 @type tuple or list 295 @type tuple or list
290 @param attribute id of the value to extract 296 @param attribute id of the value to extract
291 @type str 297 @type str
292 @return value of the attribute 298 @return value of the attribute
300 return getattr(var, attribute, None) 306 return getattr(var, attribute, None)
301 307
302 for v in var: 308 for v in var:
303 if id(v) == attribute: 309 if id(v) == attribute:
304 return v 310 return v
305 311
306 return None 312 return None
307 313
308 def getVariableList(self, var): 314 def getVariableList(self, var):
309 """ 315 """
310 Public method to get the attributes of a variable as a list. 316 Public method to get the attributes of a variable as a list.
311 317
312 @param var variable to be converted 318 @param var variable to be converted
313 @type any 319 @type any
314 @yield tuple containing the batch start index and a list 320 @yield tuple containing the batch start index and a list
315 containing the variable attributes 321 containing the variable attributes
316 @ytype tuple of (int, list) 322 @ytype tuple of (int, list)
323 if count >= BatchSize: 329 if count >= BatchSize:
324 yield start, d 330 yield start, d
325 start += count 331 start += count
326 count = 0 332 count = 0
327 d = [] 333 d = []
328 334
329 if d: 335 if d:
330 yield start, d 336 yield start, d
331 337
332 # in case it has additional fields 338 # in case it has additional fields
333 d = super().getVariableList(var) 339 d = super().getVariableList(var)
334 yield -1, d 340 yield -1, d
335 341
336 while True: 342 while True:
337 yield -2, [] 343 yield -2, []
338 344
339 345
340 ############################################################ 346 ############################################################
341 ## Resolver for Numpy Arrays 347 ## Resolver for Numpy Arrays
342 ############################################################ 348 ############################################################
343 349
344 350
345 class NdArrayResolver(BaseResolver): 351 class NdArrayResolver(BaseResolver):
346 """ 352 """
347 Class used to resolve from numpy ndarray including some meta data. 353 Class used to resolve from numpy ndarray including some meta data.
348 """ 354 """
355
349 def __isNumeric(self, arr): 356 def __isNumeric(self, arr):
350 """ 357 """
351 Private method to check, if an array is of a numeric type. 358 Private method to check, if an array is of a numeric type.
352 359
353 @param arr array to check 360 @param arr array to check
354 @type ndarray 361 @type ndarray
355 @return flag indicating a numeric array 362 @return flag indicating a numeric array
356 @rtype bool 363 @rtype bool
357 """ 364 """
358 try: 365 try:
359 return arr.dtype.kind in 'biufc' 366 return arr.dtype.kind in "biufc"
360 except AttributeError: 367 except AttributeError:
361 return False 368 return False
362 369
363 def resolve(self, var, attribute): 370 def resolve(self, var, attribute):
364 """ 371 """
365 Public method to get an attribute from a variable. 372 Public method to get an attribute from a variable.
366 373
367 @param var variable to extract an attribute or value from 374 @param var variable to extract an attribute or value from
368 @type ndarray 375 @type ndarray
369 @param attribute id of the value to extract 376 @param attribute id of the value to extract
370 @type str 377 @type str
371 @return value of the attribute 378 @return value of the attribute
372 @rtype any 379 @rtype any
373 """ 380 """
374 if attribute == 'min': 381 if attribute == "min":
375 if self.__isNumeric(var): 382 if self.__isNumeric(var):
376 return var.min() 383 return var.min()
377 else: 384 else:
378 return None 385 return None
379 386
380 if attribute == 'max': 387 if attribute == "max":
381 if self.__isNumeric(var): 388 if self.__isNumeric(var):
382 return var.max() 389 return var.max()
383 else: 390 else:
384 return None 391 return None
385 392
386 if attribute == 'mean': 393 if attribute == "mean":
387 if self.__isNumeric(var): 394 if self.__isNumeric(var):
388 return var.mean() 395 return var.mean()
389 else: 396 else:
390 return None 397 return None
391 398
392 try: 399 try:
393 return var[int(attribute)] 400 return var[int(attribute)]
394 except Exception: 401 except Exception:
395 return getattr(var, attribute, None) 402 return getattr(var, attribute, None)
396 403
397 return None 404 return None
398 405
399 def getVariableList(self, var): 406 def getVariableList(self, var):
400 """ 407 """
401 Public method to get the attributes of a variable as a list. 408 Public method to get the attributes of a variable as a list.
402 409
403 @param var variable to be converted 410 @param var variable to be converted
404 @type any 411 @type any
405 @yield tuple containing the batch start index and a list 412 @yield tuple containing the batch start index and a list
406 containing the variable attributes 413 containing the variable attributes
407 @ytype tuple of (int, list) 414 @ytype tuple of (int, list)
411 try: 418 try:
412 len(var) # Check if it's an unsized object, e.g. np.ndarray(()) 419 len(var) # Check if it's an unsized object, e.g. np.ndarray(())
413 allItems = var.tolist() 420 allItems = var.tolist()
414 except TypeError: # TypeError: len() of unsized object 421 except TypeError: # TypeError: len() of unsized object
415 allItems = [] 422 allItems = []
416 423
417 for idx, value in enumerate(allItems): 424 for idx, value in enumerate(allItems):
418 d.append((str(idx), value)) 425 d.append((str(idx), value))
419 count += 1 426 count += 1
420 if count >= BatchSize: 427 if count >= BatchSize:
421 yield start, d 428 yield start, d
422 start += count 429 start += count
423 count = 0 430 count = 0
424 d = [] 431 d = []
425 432
426 if d: 433 if d:
427 yield start, d 434 yield start, d
428 435
429 # in case it has additional fields 436 # in case it has additional fields
430 d = super().getVariableList(var) 437 d = super().getVariableList(var)
431 438
432 if var.size > 1024 * 1024: 439 if var.size > 1024 * 1024:
433 d.append( 440 d.append(
434 ('min', 441 ("min", "ndarray too big, calculating min would slow down debugging")
435 'ndarray too big, calculating min would slow down debugging')
436 ) 442 )
437 d.append( 443 d.append(
438 ('max', 444 ("max", "ndarray too big, calculating max would slow down debugging")
439 'ndarray too big, calculating max would slow down debugging')
440 ) 445 )
441 d.append( 446 d.append(
442 ('mean', 447 ("mean", "ndarray too big, calculating mean would slow down debugging")
443 'ndarray too big, calculating mean would slow down debugging')
444 ) 448 )
445 elif self.__isNumeric(var): 449 elif self.__isNumeric(var):
446 if var.size == 0: 450 if var.size == 0:
447 d.append(('min', 'empty array')) 451 d.append(("min", "empty array"))
448 d.append(('max', 'empty array')) 452 d.append(("max", "empty array"))
449 d.append(('mean', 'empty array')) 453 d.append(("mean", "empty array"))
450 else: 454 else:
451 d.append(('min', var.min())) 455 d.append(("min", var.min()))
452 d.append(('max', var.max())) 456 d.append(("max", var.max()))
453 d.append(('mean', var.mean())) 457 d.append(("mean", var.mean()))
454 else: 458 else:
455 d.append(('min', 'not a numeric object')) 459 d.append(("min", "not a numeric object"))
456 d.append(('max', 'not a numeric object')) 460 d.append(("max", "not a numeric object"))
457 d.append(('mean', 'not a numeric object')) 461 d.append(("mean", "not a numeric object"))
458 462
459 yield -1, d 463 yield -1, d
460 464
461 while True: 465 while True:
462 yield -2, [] 466 yield -2, []
463 467
464 468
465 ############################################################ 469 ############################################################
469 473
470 class MultiValueDictResolver(DictResolver): 474 class MultiValueDictResolver(DictResolver):
471 """ 475 """
472 Class used to resolve from Django multi value dictionaries. 476 Class used to resolve from Django multi value dictionaries.
473 """ 477 """
478
474 def resolve(self, var, attribute): 479 def resolve(self, var, attribute):
475 """ 480 """
476 Public method to get an attribute from a variable. 481 Public method to get an attribute from a variable.
477 482
478 @param var variable to extract an attribute or value from 483 @param var variable to extract an attribute or value from
479 @type MultiValueDict 484 @type MultiValueDict
480 @param attribute name of the attribute to extract 485 @param attribute name of the attribute to extract
481 @type str 486 @type str
482 @return value of the attribute 487 @return value of the attribute
485 if " (ID:" not in attribute: 490 if " (ID:" not in attribute:
486 try: 491 try:
487 return var[attribute] 492 return var[attribute]
488 except Exception: 493 except Exception:
489 return getattr(var, attribute, None) 494 return getattr(var, attribute, None)
490 495
491 expectedID = int(attribute.split(" (ID:")[-1][:-1]) 496 expectedID = int(attribute.split(" (ID:")[-1][:-1])
492 for key in var: 497 for key in var:
493 if id(key) == expectedID: 498 if id(key) == expectedID:
494 return var.getlist(key) 499 return var.getlist(key)
495 500
496 return None 501 return None
497 502
498 def getVariableList(self, var): 503 def getVariableList(self, var):
499 """ 504 """
500 Public method to get the attributes of a variable as a list. 505 Public method to get the attributes of a variable as a list.
501 506
502 @param var variable to be converted 507 @param var variable to be converted
503 @type any 508 @type any
504 @yield tuple containing the batch start index and a list 509 @yield tuple containing the batch start index and a list
505 containing the variable attributes 510 containing the variable attributes
506 @ytype tuple of (int, list) 511 @ytype tuple of (int, list)
512 # Fast path: all items from same type 517 # Fast path: all items from same type
513 allKeys.sort() 518 allKeys.sort()
514 except TypeError: 519 except TypeError:
515 # Slow path: only sort items with same type (Py3 only) 520 # Slow path: only sort items with same type (Py3 only)
516 allKeys.sort(key=lambda x: (str(x), x)) 521 allKeys.sort(key=lambda x: (str(x), x))
517 522
518 for key in allKeys: 523 for key in allKeys:
519 dkey = "{0} (ID:{1})".format(self.keyToStr(key), id(key)) 524 dkey = "{0} (ID:{1})".format(self.keyToStr(key), id(key))
520 d.append((dkey, var.getlist(key))) 525 d.append((dkey, var.getlist(key)))
521 count += 1 526 count += 1
522 if count >= BatchSize: 527 if count >= BatchSize:
523 yield start, d 528 yield start, d
524 start += count 529 start += count
525 count = 0 530 count = 0
526 d = [] 531 d = []
527 532
528 if d: 533 if d:
529 yield start, d 534 yield start, d
530 535
531 # in case it has additional fields 536 # in case it has additional fields
532 d = super(DictResolver, self).getVariableList(var) 537 d = super(DictResolver, self).getVariableList(var)
533 yield -1, d 538 yield -1, d
534 539
535 while True: 540 while True:
536 yield -2, [] 541 yield -2, []
537 542
538 543
539 ############################################################ 544 ############################################################
540 ## Resolver for array.array 545 ## Resolver for array.array
541 ############################################################ 546 ############################################################
542 547
543 548
544 class ArrayResolver(BaseResolver): 549 class ArrayResolver(BaseResolver):
545 """ 550 """
546 Class used to resolve from array.array including some meta data. 551 Class used to resolve from array.array including some meta data.
547 """ 552 """
553
548 TypeCodeMap = { 554 TypeCodeMap = {
549 "b": "int (signed char)", 555 "b": "int (signed char)",
550 "B": "int (unsigned char)", 556 "B": "int (unsigned char)",
551 "u": "Unicode character (Py_UNICODE)", 557 "u": "Unicode character (Py_UNICODE)",
552 "h": "int (signed short)", 558 "h": "int (signed short)",
558 "q": "int (signed long long)", 564 "q": "int (signed long long)",
559 "Q": "int (unsigned long long)", 565 "Q": "int (unsigned long long)",
560 "f": "float (float)", 566 "f": "float (float)",
561 "d": "float (double)", 567 "d": "float (double)",
562 } 568 }
563 569
564 def resolve(self, var, attribute): 570 def resolve(self, var, attribute):
565 """ 571 """
566 Public method to get an attribute from a variable. 572 Public method to get an attribute from a variable.
567 573
568 @param var variable to extract an attribute or value from 574 @param var variable to extract an attribute or value from
569 @type array.array 575 @type array.array
570 @param attribute id of the value to extract 576 @param attribute id of the value to extract
571 @type str 577 @type str
572 @return value of the attribute 578 @return value of the attribute
574 """ 580 """
575 try: 581 try:
576 return var[int(attribute)] 582 return var[int(attribute)]
577 except Exception: 583 except Exception:
578 return getattr(var, attribute, None) 584 return getattr(var, attribute, None)
579 585
580 return None 586 return None
581 587
582 def getVariableList(self, var): 588 def getVariableList(self, var):
583 """ 589 """
584 Public method to get the attributes of a variable as a list. 590 Public method to get the attributes of a variable as a list.
585 591
586 @param var variable to be converted 592 @param var variable to be converted
587 @type any 593 @type any
588 @yield tuple containing the batch start index and a list 594 @yield tuple containing the batch start index and a list
589 containing the variable attributes 595 containing the variable attributes
590 @ytype tuple of (int, list) 596 @ytype tuple of (int, list)
591 """ 597 """
592 d = [] 598 d = []
593 start = count = 0 599 start = count = 0
594 allItems = var.tolist() 600 allItems = var.tolist()
595 601
596 for idx, value in enumerate(allItems): 602 for idx, value in enumerate(allItems):
597 d.append((str(idx), value)) 603 d.append((str(idx), value))
598 count += 1 604 count += 1
599 if count >= BatchSize: 605 if count >= BatchSize:
600 yield start, d 606 yield start, d
601 start += count 607 start += count
602 count = 0 608 count = 0
603 d = [] 609 d = []
604 610
605 if d: 611 if d:
606 yield start, d 612 yield start, d
607 613
608 # in case it has additional fields 614 # in case it has additional fields
609 d = super().getVariableList(var) 615 d = super().getVariableList(var)
610 616
611 # Special data for array type: convert typecode to readable text 617 # Special data for array type: convert typecode to readable text
612 d.append(('type', self.TypeCodeMap.get(var.typecode, 'illegal type'))) 618 d.append(("type", self.TypeCodeMap.get(var.typecode, "illegal type")))
613 619
614 yield -1, d 620 yield -1, d
615 621
616 while True: 622 while True:
617 yield -2, [] 623 yield -2, []
618 624
619 625
620 ############################################################ 626 ############################################################
624 630
625 class QtResolver(BaseResolver): 631 class QtResolver(BaseResolver):
626 """ 632 """
627 Class used to resolve the Qt implementations. 633 Class used to resolve the Qt implementations.
628 """ 634 """
635
629 def resolve(self, var, attribute): 636 def resolve(self, var, attribute):
630 """ 637 """
631 Public method to get an attribute from a variable. 638 Public method to get an attribute from a variable.
632 639
633 @param var variable to extract an attribute or value from 640 @param var variable to extract an attribute or value from
634 @type Qt objects 641 @type Qt objects
635 @param attribute name of the attribute to extract 642 @param attribute name of the attribute to extract
636 @type str 643 @type str
637 @return value of the attribute 644 @return value of the attribute
638 @rtype any 645 @rtype any
639 """ 646 """
640 if attribute == 'internalPointer': 647 if attribute == "internalPointer":
641 return var.internalPointer() 648 return var.internalPointer()
642 649
643 return getattr(var, attribute, None) 650 return getattr(var, attribute, None)
644 651
645 def getVariableList(self, var): 652 def getVariableList(self, var):
646 """ 653 """
647 Public method to get the attributes of a variable as a list. 654 Public method to get the attributes of a variable as a list.
648 655
649 @param var variable to be converted 656 @param var variable to be converted
650 @type any 657 @type any
651 @yield tuple containing the batch start index and a list 658 @yield tuple containing the batch start index and a list
652 containing the variable attributes 659 containing the variable attributes
653 @ytype tuple of (int, list) 660 @ytype tuple of (int, list)
656 attributes = () 663 attributes = ()
657 # Gently handle exception which could occure as special 664 # Gently handle exception which could occure as special
658 # cases, e.g. already deleted C++ objects, str conversion.. 665 # cases, e.g. already deleted C++ objects, str conversion..
659 with contextlib.suppress(Exception): 666 with contextlib.suppress(Exception):
660 qttype = type(var).__name__ 667 qttype = type(var).__name__
661 668
662 if qttype in ('QLabel', 'QPushButton'): 669 if qttype in ("QLabel", "QPushButton"):
663 attributes = ('text', ) 670 attributes = ("text",)
664 elif qttype == 'QByteArray': 671 elif qttype == "QByteArray":
665 d.append(('bytes', bytes(var))) 672 d.append(("bytes", bytes(var)))
666 d.append(('hex', "QByteArray", "{0}".format(var.toHex()))) 673 d.append(("hex", "QByteArray", "{0}".format(var.toHex())))
674 d.append(("base64", "QByteArray", "{0}".format(var.toBase64())))
667 d.append( 675 d.append(
668 ('base64', "QByteArray", 676 (
669 "{0}".format(var.toBase64())) 677 "percent encoding",
678 "QByteArray",
679 "{0}".format(var.toPercentEncoding()),
680 )
670 ) 681 )
671 d.append( 682 elif qttype in ("QPoint", "QPointF"):
672 ('percent encoding', "QByteArray", 683 attributes = ("x", "y")
673 "{0}".format(var.toPercentEncoding())) 684 elif qttype in ("QRect", "QRectF"):
674 ) 685 attributes = ("x", "y", "width", "height")
675 elif qttype in ('QPoint', 'QPointF'): 686 elif qttype in ("QSize", "QSizeF"):
676 attributes = ('x', 'y') 687 attributes = ("width", "height")
677 elif qttype in ('QRect', 'QRectF'): 688 elif qttype == "QColor":
678 attributes = ('x', 'y', 'width', 'height') 689 attributes = ("name",)
679 elif qttype in ('QSize', 'QSizeF'):
680 attributes = ('width', 'height')
681 elif qttype == 'QColor':
682 attributes = ('name', )
683 r, g, b, a = var.getRgb() 690 r, g, b, a = var.getRgb()
684 d.append( 691 d.append(("rgba", "{0:d}, {1:d}, {2:d}, {3:d}".format(r, g, b, a)))
685 ('rgba', "{0:d}, {1:d}, {2:d}, {3:d}".format(r, g, b, a))
686 )
687 h, s, v, a = var.getHsv() 692 h, s, v, a = var.getHsv()
688 d.append( 693 d.append(("hsva", "{0:d}, {1:d}, {2:d}, {3:d}".format(h, s, v, a)))
689 ('hsva', "{0:d}, {1:d}, {2:d}, {3:d}".format(h, s, v, a))
690 )
691 c, m, y, k, a = var.getCmyk() 694 c, m, y, k, a = var.getCmyk()
692 d.append( 695 d.append(
693 ('cmyka', 696 ("cmyka", "{0:d}, {1:d}, {2:d}, {3:d}, {4:d}".format(c, m, y, k, a))
694 "{0:d}, {1:d}, {2:d}, {3:d}, {4:d}".format(c, m, y, k, a))
695 ) 697 )
696 elif qttype in ('QDate', 'QTime', 'QDateTime'): 698 elif qttype in ("QDate", "QTime", "QDateTime"):
697 d.append((qttype[1:].lower(), var.toString())) 699 d.append((qttype[1:].lower(), var.toString()))
698 elif qttype == 'QDir': 700 elif qttype == "QDir":
699 attributes = ('path', 'absolutePath', 'canonicalPath') 701 attributes = ("path", "absolutePath", "canonicalPath")
700 elif qttype == 'QFile': 702 elif qttype == "QFile":
701 attributes = ('fileName', ) 703 attributes = ("fileName",)
702 elif qttype == 'QFont': 704 elif qttype == "QFont":
703 attributes = ( 705 attributes = ("family", "pointSize", "weight", "bold", "italic")
704 'family', 'pointSize', 'weight', 'bold', 'italic' 706 elif qttype == "QUrl":
705 ) 707 d.append(("url", var.toString()))
706 elif qttype == 'QUrl': 708 attributes = ("scheme", "userName", "password", "host", "port", "path")
707 d.append(('url', var.toString())) 709 elif qttype == "QModelIndex":
708 attributes = ('scheme', 'userName', 'password', 'host', 'port',
709 'path')
710 elif qttype == 'QModelIndex':
711 valid = var.isValid() 710 valid = var.isValid()
712 d.append(('valid', valid)) 711 d.append(("valid", valid))
713 if valid: 712 if valid:
714 d.append(("internalPointer", var.internalPointer())) 713 d.append(("internalPointer", var.internalPointer()))
715 attributes = ('row', 'column', 'internalId') 714 attributes = ("row", "column", "internalId")
716 elif qttype in ('QRegExp', "QRegularExpression"): 715 elif qttype in ("QRegExp", "QRegularExpression"):
717 attributes = ('pattern', ) 716 attributes = ("pattern",)
718 717
719 # GUI stuff 718 # GUI stuff
720 elif qttype == 'QAction': 719 elif qttype == "QAction":
721 d.append(('shortcut', var.shortcut().toString())) 720 d.append(("shortcut", var.shortcut().toString()))
722 attributes = ('objectName', 'text', 'iconText', 'toolTip', 721 attributes = ("objectName", "text", "iconText", "toolTip", "whatsThis")
723 'whatsThis') 722
724 723 elif qttype == "QKeySequence":
725 elif qttype == 'QKeySequence': 724 d.append(("keySequence", var.toString()))
726 d.append(('keySequence', var.toString())) 725
727
728 # XML stuff 726 # XML stuff
729 elif qttype == 'QDomAttr': 727 elif qttype == "QDomAttr":
730 attributes = ('name', 'var') 728 attributes = ("name", "var")
731 elif qttype in ('QDomCharacterData', 'QDomComment', 'QDomText'): 729 elif qttype in ("QDomCharacterData", "QDomComment", "QDomText"):
732 attributes = ('data', ) 730 attributes = ("data",)
733 elif qttype == 'QDomDocument': 731 elif qttype == "QDomDocument":
734 d.append(('text', var.toString())) 732 d.append(("text", var.toString()))
735 elif qttype == 'QDomElement': 733 elif qttype == "QDomElement":
736 attributes = ('tagName', 'text') 734 attributes = ("tagName", "text")
737 735
738 # Networking stuff 736 # Networking stuff
739 elif qttype == 'QHostAddress': 737 elif qttype == "QHostAddress":
740 d.append(('address', var.toString())) 738 d.append(("address", var.toString()))
741 739
742 # PySide specific 740 # PySide specific
743 elif qttype == 'EnumType': # Not in PyQt possible 741 elif qttype == "EnumType": # Not in PyQt possible
744 for key, value in var.values.items(): 742 for key, value in var.values.items():
745 d.append((key, int(value))) 743 d.append((key, int(value)))
746 744
747 for attribute in attributes: 745 for attribute in attributes:
748 d.append((attribute, getattr(var, attribute)())) 746 d.append((attribute, getattr(var, attribute)()))
749 747
750 # add additional fields 748 # add additional fields
751 if qttype != 'EnumType': 749 if qttype != "EnumType":
752 d.extend(super().getVariableList(var)) 750 d.extend(super().getVariableList(var))
753 751
754 yield -1, d 752 yield -1, d
755 while True: 753 while True:
756 yield -2, [] 754 yield -2, []
757 755
758 756
780 def _initTypeMap(): 778 def _initTypeMap():
781 """ 779 """
782 Protected function to initialize the type map. 780 Protected function to initialize the type map.
783 """ 781 """
784 global _TypeMap 782 global _TypeMap
785 783
786 # Type map for special handling of array types. 784 # Type map for special handling of array types.
787 # All other types not listed here use the default resolver. 785 # All other types not listed here use the default resolver.
788 _TypeMap = [ 786 _TypeMap = [
789 (tuple, listResolver), 787 (tuple, listResolver),
790 (list, listResolver), 788 (list, listResolver),
804 def updateTypeMap(): 802 def updateTypeMap():
805 """ 803 """
806 Public function to update the type map based on module imports. 804 Public function to update the type map based on module imports.
807 """ 805 """
808 global _TypeMap, _ArrayTypes, _TryArray, _TryNumpy, _TryDjango, _MapCount 806 global _TypeMap, _ArrayTypes, _TryArray, _TryNumpy, _TryDjango, _MapCount
809 807
810 # array.array may not be imported (yet) 808 # array.array may not be imported (yet)
811 if _TryArray and 'array' in sys.modules: 809 if _TryArray and "array" in sys.modules:
812 import array 810 import array
811
813 _TypeMap.append((array.array, arrayResolver)) 812 _TypeMap.append((array.array, arrayResolver))
814 _TryArray = False 813 _TryArray = False
815 814
816 # numpy may not be imported (yet) 815 # numpy may not be imported (yet)
817 if _TryNumpy and 'numpy' in sys.modules: 816 if _TryNumpy and "numpy" in sys.modules:
818 import numpy 817 import numpy
818
819 _TypeMap.append((numpy.ndarray, ndarrayResolver)) 819 _TypeMap.append((numpy.ndarray, ndarrayResolver))
820 _TryNumpy = False 820 _TryNumpy = False
821 821
822 # django may not be imported (yet) 822 # django may not be imported (yet)
823 if _TryDjango and 'django' in sys.modules: 823 if _TryDjango and "django" in sys.modules:
824 from django.utils.datastructures import MultiValueDict 824 from django.utils.datastructures import MultiValueDict
825
825 # it should go before dict 826 # it should go before dict
826 _TypeMap.insert(0, (MultiValueDict, multiValueDictResolver)) 827 _TypeMap.insert(0, (MultiValueDict, multiValueDictResolver))
827 _TryDjango = False 828 _TryDjango = False
828 829
829 # If _TypeMap changed, rebuild the _ArrayTypes tuple 830 # If _TypeMap changed, rebuild the _ArrayTypes tuple
830 if _MapCount != len(_TypeMap): 831 if _MapCount != len(_TypeMap):
831 _ArrayTypes = tuple(typ for typ, _resolver in _TypeMap) 832 _ArrayTypes = tuple(typ for typ, _resolver in _TypeMap)
832 _MapCount = len(_TypeMap) 833 _MapCount = len(_TypeMap)
833 834
834 835
835 def getResolver(obj): 836 def getResolver(obj):
836 """ 837 """
837 Public method to get the resolver based on the type info of an object. 838 Public method to get the resolver based on the type info of an object.
838 839
839 @param obj object to get resolver for 840 @param obj object to get resolver for
840 @type any 841 @type any
841 @return resolver 842 @return resolver
842 @rtype BaseResolver 843 @rtype BaseResolver
843 """ 844 """
844 # Between PyQt and PySide the returned type is different (class vs. type) 845 # Between PyQt and PySide the returned type is different (class vs. type)
845 typeStr = str(type(obj)).split(' ', 1)[-1] 846 typeStr = str(type(obj)).split(" ", 1)[-1]
846 typeStr = typeStr[1:-2] 847 typeStr = typeStr[1:-2]
847 848
848 if ( 849 if typeStr.startswith(ConfigQtNames) and typeStr.endswith(ConfigKnownQtTypes):
849 typeStr.startswith(ConfigQtNames) and
850 typeStr.endswith(ConfigKnownQtTypes)
851 ):
852 return qtResolver 850 return qtResolver
853 851
854 for typeData, resolver in _TypeMap: # __IGNORE_WARNING_M507__ 852 for typeData, resolver in _TypeMap: # __IGNORE_WARNING_M507__
855 if isinstance(obj, typeData): 853 if isinstance(obj, typeData):
856 return resolver 854 return resolver
857 855
858 return defaultResolver 856 return defaultResolver
857
859 858
860 # 859 #
861 # eflag: noqa = Y113 860 # eflag: noqa = Y113

eric ide

mercurial