| 453 | |
| 454 | |
| 455 | class TupleResolver: # to enumerate tuples and lists |
| 456 | def resolve(self, var, attribute): |
| 457 | """ |
| 458 | :param var: that's the original object we're dealing with. |
| 459 | :param attribute: that's the key to resolve |
| 460 | -- either the dict key in get_dictionary or the name in the dap protocol. |
| 461 | """ |
| 462 | if attribute in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR): |
| 463 | return None |
| 464 | try: |
| 465 | return var[int(attribute)] |
| 466 | except: |
| 467 | if attribute == "more": |
| 468 | return MoreItems(var, pydevd_constants.PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS) |
| 469 | |
| 470 | return getattr(var, attribute) |
| 471 | |
| 472 | def get_contents_debug_adapter_protocol(self, lst, fmt=None): |
| 473 | """ |
| 474 | This method is to be used in the case where the variables are all saved by its id (and as |
| 475 | such don't need to have the `resolve` method called later on, so, keys don't need to |
| 476 | embed the reference in the key). |
| 477 | |
| 478 | Note that the return should be ordered. |
| 479 | |
| 480 | :return list(tuple(name:str, value:object, evaluateName:str)) |
| 481 | """ |
| 482 | lst_len = len(lst) |
| 483 | ret = [] |
| 484 | |
| 485 | format_str = "%0" + str(int(len(str(lst_len - 1)))) + "d" |
| 486 | if fmt is not None and fmt.get("hex", False): |
| 487 | format_str = "0x%0" + str(int(len(hex(lst_len).lstrip("0x")))) + "x" |
| 488 | |
| 489 | initial_expanded = pydevd_constants.PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS |
| 490 | for i, item in enumerate(lst): |
| 491 | ret.append((format_str % i, item, "[%s]" % i)) |
| 492 | |
| 493 | if i >= initial_expanded - 1: |
| 494 | if (lst_len - initial_expanded) < pydevd_constants.PYDEVD_CONTAINER_BUCKET_SIZE: |
| 495 | # Special case: if we have just 1 more bucket just put it inline. |
| 496 | item = MoreItemsRange(lst, initial_expanded, lst_len) |
| 497 | |
| 498 | else: |
| 499 | # Multiple buckets |
| 500 | item = MoreItems(lst, initial_expanded) |
| 501 | ret.append(("more", item, None)) |
| 502 | break |
| 503 | |
| 504 | # Needed in case the class extends the built-in type and has some additional fields. |
| 505 | from_default_resolver = defaultResolver.get_contents_debug_adapter_protocol(lst, fmt=fmt) |
| 506 | if from_default_resolver: |
| 507 | ret = from_default_resolver + ret |
| 508 | |
| 509 | ret.append((GENERATED_LEN_ATTR_NAME, len(lst), partial(_apply_evaluate_name, evaluate_name="len(%s)"))) |
| 510 | return ret |
| 511 | |
| 512 | def get_dictionary(self, var, fmt={}): |
no outgoing calls