Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ def _does_obj_repr_evaluate_to_obj(obj):


# =======================================================================================================================
# DictResolver
# MappingResolver
# =======================================================================================================================
class DictResolver:
class MappingResolver:
sort_keys = not IS_PY36_OR_GREATER

def resolve(self, dct, key):
Expand Down Expand Up @@ -452,7 +452,7 @@ def resolve(self, var, attribute):
return var.resolve(attribute)


class TupleResolver: # to enumerate tuples and lists
class SequenceResolver:
def resolve(self, var, attribute):
"""
:param var: that's the original object we're dealing with.
Expand Down Expand Up @@ -657,7 +657,7 @@ def get_dictionary(self, obj):
# =======================================================================================================================
# MultiValueDictResolver
# =======================================================================================================================
class MultiValueDictResolver(DictResolver):
class MultiValueDictResolver(MappingResolver):
def resolve(self, dct, key):
if key in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR):
return None
Expand Down Expand Up @@ -699,17 +699,17 @@ def get_dictionary(self, var, names=None):
# =======================================================================================================================
# DequeResolver
# =======================================================================================================================
class DequeResolver(TupleResolver):
class DequeResolver(SequenceResolver):
def get_dictionary(self, var):
d = TupleResolver.get_dictionary(self, var)
d = SequenceResolver.get_dictionary(self, var)
d["maxlen"] = getattr(var, "maxlen", None)
return d


# =======================================================================================================================
# OrderedDictResolver
# =======================================================================================================================
class OrderedDictResolver(DictResolver):
class OrderedDictResolver(MappingResolver):
sort_keys = False

def init_dict(self):
Expand Down Expand Up @@ -765,8 +765,8 @@ def get_frame_name(self, frame):


defaultResolver = DefaultResolver()
dictResolver = DictResolver()
tupleResolver = TupleResolver()
mappingResolver = MappingResolver()
sequenceResolver = SequenceResolver()
instanceResolver = InstanceResolver()
jyArrayResolver = JyArrayResolver()
setResolver = SetResolver()
Expand Down
118 changes: 33 additions & 85 deletions src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_xml.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import sys

from collections import deque, OrderedDict
from collections.abc import Mapping, Sequence, Set as AbstractSet
from types import FrameType
from typing import Optional

from _pydev_bundle import pydev_log
from _pydevd_bundle import pydevd_extension_utils
from _pydevd_bundle import pydevd_resolver
import sys
from _pydevd_bundle.pydevd_constants import (
BUILTINS_MODULE_NAME,
MAXIMUM_VARIABLE_REPRESENTATION_SIZE,
Expand All @@ -13,14 +19,6 @@
from _pydevd_bundle.pydevd_extension_api import TypeResolveProvider, StrPresentationProvider
from _pydevd_bundle.pydevd_utils import isinstance_checked, hasattr_checked, DAPGrouper
from _pydevd_bundle.pydevd_resolver import get_var_scope, MoreItems, MoreItemsRange
from typing import Optional

try:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is still required for pre 3.11? There is no FrameType in 3.10.

import types

frame_type = types.FrameType
except:
frame_type = None


def make_valid_xml_value(s):
Expand All @@ -40,97 +38,47 @@ def __init__(self, result, etype, tb):

def _create_default_type_map():
default_type_map = [
# None means that it should not be treated as a compound variable
# isintance does not accept a tuple on some versions of python, so, we must declare it expanded
(
type(None),
None,
),
(int, None),
(float, None),
(complex, None),
(str, None),
(tuple, pydevd_resolver.tupleResolver),
(list, pydevd_resolver.tupleResolver),
(dict, pydevd_resolver.dictResolver),
# non-compound types
((type(None), int, float, complex, str), None),
# collections
(Sequence, pydevd_resolver.sequenceResolver),
(deque, pydevd_resolver.dequeResolver),
(OrderedDict, pydevd_resolver.orderedDictResolver),
(Mapping, pydevd_resolver.mappingResolver),
(AbstractSet, pydevd_resolver.setResolver),
# other builtin types
(FrameType, pydevd_resolver.frameResolver),
# pydevd types
(DAPGrouper, pydevd_resolver.dapGrouperResolver),
((MoreItems, MoreItemsRange), pydevd_resolver.forwardInternalResolverToObject),
]
try:
from collections import OrderedDict

default_type_map.insert(0, (OrderedDict, pydevd_resolver.orderedDictResolver))
# we should put it before dict
except:
pass

try:
default_type_map.append((long, None)) # @UndefinedVariable
except:
pass # not available on all python versions

default_type_map.append((DAPGrouper, pydevd_resolver.dapGrouperResolver))
default_type_map.append((MoreItems, pydevd_resolver.forwardInternalResolverToObject))
default_type_map.append((MoreItemsRange, pydevd_resolver.forwardInternalResolverToObject))

try:
default_type_map.append((set, pydevd_resolver.setResolver))
except:
pass # not available on all python versions

try:
default_type_map.append((frozenset, pydevd_resolver.setResolver))
except:
pass # not available on all python versions

try:
from django.utils.datastructures import MultiValueDict

from django.forms import BaseForm
except ImportError:
pass # django may not be installed
else:
default_type_map.insert(0, (MultiValueDict, pydevd_resolver.multiValueDictResolver))
# we should put it before dict
except:
pass # django may not be installed

try:
from django.forms import BaseForm

default_type_map.insert(0, (BaseForm, pydevd_resolver.djangoFormResolver))
# we should put it before instance resolver
except:
pass # django may not be installed

try:
from collections import deque

default_type_map.append((deque, pydevd_resolver.dequeResolver))
except:
pass

try:
from ctypes import Array

default_type_map.append((Array, pydevd_resolver.tupleResolver))
except:
pass

if frame_type is not None:
default_type_map.append((frame_type, pydevd_resolver.frameResolver))
except ImportError:
pass # TODO: comment on reason why this might this not be available
else:
default_type_map.append((Array, pydevd_resolver.sequenceResolver))

if _IS_JYTHON:
from org.python import core # @UnresolvedImport

default_type_map.append((core.PyNone, None))
default_type_map.append((core.PyInteger, None))
default_type_map.append((core.PyLong, None))
default_type_map.append((core.PyFloat, None))
default_type_map.append((core.PyComplex, None))
default_type_map.append((core.PyString, None))
default_type_map.append((core.PyTuple, pydevd_resolver.tupleResolver))
default_type_map.append((core.PyList, pydevd_resolver.tupleResolver))
default_type_map.append((core.PyDictionary, pydevd_resolver.dictResolver))
default_type_map.append((core.PyStringMap, pydevd_resolver.dictResolver))

if hasattr(core, "PyJavaInstance"):
# Jython 2.5b3 removed it.
default_type_map.append((core.PyJavaInstance, pydevd_resolver.instanceResolver))
default_type_map += [
((core.PyNone, core.PyInteger, core.PyLong, core.PyFloat, core.PyComplex, core.PyString), None),
((core.PyTuple, core.PyList), pydevd_resolver.sequenceResolver),
((core.PyDictionary, core.PyStringMap), pydevd_resolver.mappingResolver),
]

return default_type_map

Expand Down
71 changes: 41 additions & 30 deletions src/debugpy/_vendored/pydevd/tests_python/test_resolvers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
from __future__ import annotations

import sys
from types import MappingProxyType
from typing import TYPE_CHECKING
from collections import UserDict, UserList

import pytest
from _pydevd_bundle.pydevd_constants import IS_PY36_OR_GREATER, GENERATED_LEN_ATTR_NAME
from _pydevd_bundle import pydevd_constants, pydevd_frame_utils
import pytest
import sys

if TYPE_CHECKING:
from collections.abc import Mapping, Sequence


def check_len_entry(len_entry, first_2_params):
Expand All @@ -10,12 +19,13 @@ def check_len_entry(len_entry, first_2_params):
assert len_entry[2]("check") == "len(check)"


def test_dict_resolver():
from _pydevd_bundle.pydevd_resolver import DictResolver
@pytest.mark.parametrize("map_cls", [dict, MappingProxyType, UserDict])
def test_mapping_resolver(map_cls: type[Mapping]):
from _pydevd_bundle.pydevd_resolver import MappingResolver

dict_resolver = DictResolver()
dct = {(1, 2): 2, "22": 22}
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(dict_resolver.get_contents_debug_adapter_protocol(dct))
mapping_resolver = MappingResolver()
dct = map_cls({(1, 2): 2, "22": 22})
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(mapping_resolver.get_contents_debug_adapter_protocol(dct))
len_entry = contents_debug_adapter_protocol.pop(-1)
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 2))
if IS_PY36_OR_GREATER:
Expand All @@ -25,13 +35,13 @@ def test_dict_resolver():
assert contents_debug_adapter_protocol == [("'22'", 22, "['22']"), ("(1, 2)", 2, "[(1, 2)]")]


def test_dict_resolver_hex():
from _pydevd_bundle.pydevd_resolver import DictResolver
def test_mapping_resolver_hex():
from _pydevd_bundle.pydevd_resolver import MappingResolver

dict_resolver = DictResolver()
mapping_resolver = MappingResolver()
dct = {(1, 10, 100): (10000, 100000, 100000)}
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(
dict_resolver.get_contents_debug_adapter_protocol(dct, fmt={"hex": True})
mapping_resolver.get_contents_debug_adapter_protocol(dct, fmt={"hex": True})
)
len_entry = contents_debug_adapter_protocol.pop(-1)
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 1))
Expand Down Expand Up @@ -164,13 +174,14 @@ def clear_contents_dictionary(dictionary):
return dictionary


def test_tuple_resolver():
from _pydevd_bundle.pydevd_resolver import TupleResolver
@pytest.mark.parametrize("seq_cls", [list, tuple, UserList])
def test_sequence_resolver(seq_cls: type[Sequence]):
from _pydevd_bundle.pydevd_resolver import SequenceResolver

tuple_resolver = TupleResolver()
seq_resolver = SequenceResolver()
fmt = {"hex": True}
lst = tuple(range(11))
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(tuple_resolver.get_contents_debug_adapter_protocol(lst))
lst = seq_cls(range(11))
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(seq_resolver.get_contents_debug_adapter_protocol(lst))
len_entry = contents_debug_adapter_protocol.pop(-1)
assert contents_debug_adapter_protocol == [
("00", 0, "[0]"),
Expand All @@ -187,7 +198,7 @@ def test_tuple_resolver():
]
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 11))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst)) == {
assert clear_contents_dictionary(seq_resolver.get_dictionary(lst)) == {
"00": 0,
"01": 1,
"02": 2,
Expand All @@ -202,9 +213,9 @@ def test_tuple_resolver():
GENERATED_LEN_ATTR_NAME: 11,
}

lst = tuple(range(17))
lst = seq_cls(range(17))
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(
tuple_resolver.get_contents_debug_adapter_protocol(lst, fmt=fmt)
seq_resolver.get_contents_debug_adapter_protocol(lst, fmt=fmt)
)
len_entry = contents_debug_adapter_protocol.pop(-1)
assert contents_debug_adapter_protocol == [
Expand All @@ -228,7 +239,7 @@ def test_tuple_resolver():
]
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 17))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst, fmt=fmt)) == {
assert clear_contents_dictionary(seq_resolver.get_dictionary(lst, fmt=fmt)) == {
"0x00": 0,
"0x01": 1,
"0x02": 2,
Expand All @@ -249,8 +260,8 @@ def test_tuple_resolver():
GENERATED_LEN_ATTR_NAME: 17,
}

lst = tuple(range(10))
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(tuple_resolver.get_contents_debug_adapter_protocol(lst))
lst = seq_cls(range(10))
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(seq_resolver.get_contents_debug_adapter_protocol(lst))
len_entry = contents_debug_adapter_protocol.pop(-1)
assert contents_debug_adapter_protocol == [
("0", 0, "[0]"),
Expand All @@ -266,7 +277,7 @@ def test_tuple_resolver():
]
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 10))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst)) == {
assert clear_contents_dictionary(seq_resolver.get_dictionary(lst)) == {
"0": 0,
"1": 1,
"2": 2,
Expand All @@ -281,7 +292,7 @@ def test_tuple_resolver():
}

contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(
tuple_resolver.get_contents_debug_adapter_protocol(lst, fmt=fmt)
seq_resolver.get_contents_debug_adapter_protocol(lst, fmt=fmt)
)
len_entry = contents_debug_adapter_protocol.pop(-1)
assert contents_debug_adapter_protocol == [
Expand All @@ -298,7 +309,7 @@ def test_tuple_resolver():
]
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 10))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst, fmt=fmt)) == {
assert clear_contents_dictionary(seq_resolver.get_dictionary(lst, fmt=fmt)) == {
"0x0": 0,
"0x1": 1,
"0x2": 2,
Expand All @@ -313,17 +324,17 @@ def test_tuple_resolver():
}


def test_tuple_resolver_mixed():
from _pydevd_bundle.pydevd_resolver import TupleResolver
def test_sequence_resolver_mixed():
from _pydevd_bundle.pydevd_resolver import SequenceResolver

tuple_resolver = TupleResolver()
seq_resolver = SequenceResolver()

class CustomTuple(tuple):
pass

my_tuple = CustomTuple([1, 2])
my_tuple.some_value = 10
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(tuple_resolver.get_contents_debug_adapter_protocol(my_tuple))
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(seq_resolver.get_contents_debug_adapter_protocol(my_tuple))
len_entry = contents_debug_adapter_protocol.pop(-1)
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 2))
assert contents_debug_adapter_protocol == [
Expand All @@ -333,7 +344,7 @@ class CustomTuple(tuple):
]


def test_tuple_resolver_ctypes():
def test_sequence_resolver_ctypes():
import ctypes
from _pydevd_bundle.pydevd_xml import get_type

Expand Down
Loading