Skip to content

Commit

Permalink
Change __len__ to len().
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Apr 19, 2020
1 parent 05ffe6d commit b731a72
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def get_frame():
MAXIMUM_VARIABLE_REPRESENTATION_SIZE = 1000
# Prefix for saving functions return values in locals
RETURN_VALUES_DICT = '__pydevd_ret_val_dict'
GENERATED_LEN_ATTR_NAME = 'len()'

import os

Expand Down
29 changes: 14 additions & 15 deletions src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from functools import partial
from _pydevd_bundle.pydevd_constants import dict_iter_items, dict_keys, xrange, IS_PY36_OR_GREATER, \
MethodWrapperType, RETURN_VALUES_DICT, DebugInfoHolder, IS_PYPY
MethodWrapperType, RETURN_VALUES_DICT, DebugInfoHolder, IS_PYPY, GENERATED_LEN_ATTR_NAME
from _pydevd_bundle.pydevd_safe_repr import SafeRepr

# Note: 300 is already a lot to see in the outline (after that the user should really use the shell to get things)
Expand Down Expand Up @@ -223,7 +223,7 @@ class DictResolver:
sort_keys = not IS_PY36_OR_GREATER

def resolve(self, dict, key):
if key in ('__len__', TOO_LARGE_ATTR):
if key in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR):
return None

if '(' not in key:
Expand Down Expand Up @@ -276,7 +276,7 @@ def get_contents_debug_adapter_protocol(self, dct, fmt=None):
ret.append((TOO_LARGE_ATTR, TOO_LARGE_MSG, None))
break

ret.append(('__len__', len(dct), partial(_apply_evaluate_name, evaluate_name='len(%s)')))
ret.append((GENERATED_LEN_ATTR_NAME, len(dct), partial(_apply_evaluate_name, evaluate_name='len(%s)')))
# in case the class extends built-in type and has some additional fields
from_default_resolver = defaultResolver.get_contents_debug_adapter_protocol(dct, fmt)

Expand Down Expand Up @@ -304,7 +304,7 @@ def get_dictionary(self, dict):
# in case if the class extends built-in type and has some additional fields
additional_fields = defaultResolver.get_dictionary(dict)
ret.update(additional_fields)
ret['__len__'] = len(dict)
ret[GENERATED_LEN_ATTR_NAME] = len(dict)
return ret


Expand All @@ -322,7 +322,7 @@ def resolve(self, var, attribute):
@param var: that's the original attribute
@param attribute: that's the key passed in the dict (as a string)
'''
if attribute in ('__len__', TOO_LARGE_ATTR):
if attribute in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR):
return None
try:
return var[int(attribute)]
Expand Down Expand Up @@ -353,7 +353,7 @@ def get_contents_debug_adapter_protocol(self, lst, fmt=None):
ret.append((TOO_LARGE_ATTR, TOO_LARGE_MSG, None))
break

ret.append(('__len__', len(lst), partial(_apply_evaluate_name, evaluate_name='len(%s)')))
ret.append((GENERATED_LEN_ATTR_NAME, len(lst), partial(_apply_evaluate_name, evaluate_name='len(%s)')))
# Needed in case the class extends the built-in type and has some additional fields.
from_default_resolver = defaultResolver.get_contents_debug_adapter_protocol(lst, fmt=fmt)
if from_default_resolver:
Expand All @@ -378,7 +378,7 @@ def get_dictionary(self, var, fmt={}):
# in case if the class extends built-in type and has some additional fields
additional_fields = defaultResolver.get_dictionary(var)
d.update(additional_fields)
d['__len__'] = len(var)
d[GENERATED_LEN_ATTR_NAME] = len(var)
return d


Expand All @@ -400,15 +400,15 @@ def get_contents_debug_adapter_protocol(self, obj, fmt=None):
ret.append((TOO_LARGE_ATTR, TOO_LARGE_MSG, None))
break

ret.append(('__len__', len(obj), partial(_apply_evaluate_name, evaluate_name='len(%s)')))
ret.append((GENERATED_LEN_ATTR_NAME, len(obj), partial(_apply_evaluate_name, evaluate_name='len(%s)')))
# Needed in case the class extends the built-in type and has some additional fields.
from_default_resolver = defaultResolver.get_contents_debug_adapter_protocol(obj, fmt=fmt)
if from_default_resolver:
ret = from_default_resolver + ret
return ret

def resolve(self, var, attribute):
if attribute in ('__len__', TOO_LARGE_ATTR):
if attribute in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR):
return None

try:
Expand All @@ -434,7 +434,7 @@ def get_dictionary(self, var):
# in case if the class extends built-in type and has some additional fields
additional_fields = defaultResolver.get_dictionary(var)
d.update(additional_fields)
d['__len__'] = len(var)
d[GENERATED_LEN_ATTR_NAME] = len(var)
return d

def change_var_from_name(self, container, name, new_value):
Expand Down Expand Up @@ -490,7 +490,7 @@ class JyArrayResolver:
'''

def resolve(self, var, attribute):
if attribute == '__len__':
if attribute == GENERATED_LEN_ATTR_NAME:
return None
return var[int(attribute)]

Expand All @@ -500,7 +500,7 @@ def get_dictionary(self, obj):
for i in xrange(len(obj)):
ret[ i ] = obj[i]

ret['__len__'] = len(obj)
ret[GENERATED_LEN_ATTR_NAME] = len(obj)
return ret


Expand All @@ -510,7 +510,7 @@ def get_dictionary(self, obj):
class MultiValueDictResolver(DictResolver):

def resolve(self, dict, key):
if key in ('__len__', TOO_LARGE_ATTR):
if key in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR):
return None

# ok, we have to iterate over the items to find the one that matches the id, because that's the only way
Expand Down Expand Up @@ -660,8 +660,7 @@ def get_var_scope(attr_name, attr_value, evaluate_name, handle_return_values):
if handle_return_values and attr_name == RETURN_VALUES_DICT:
return ''

elif attr_name == '__len__' and evaluate_name != '.__len__':
# Treat the __len__ we generate internally separate from the __len__ function
elif attr_name == GENERATED_LEN_ATTR_NAME:
return ''

if attr_name.startswith('__') and attr_name.endswith('__'):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import sys

from _pydevd_bundle.pydevd_constants import get_frame, dict_items, RETURN_VALUES_DICT, \
dict_iter_items, ForkSafeLock
dict_iter_items, ForkSafeLock, GENERATED_LEN_ATTR_NAME
from _pydevd_bundle.pydevd_xml import get_variable_details, get_type
from _pydev_bundle.pydev_override import overrides
from _pydevd_bundle.pydevd_resolver import sorted_attributes_key, TOO_LARGE_ATTR, get_var_scope
Expand Down Expand Up @@ -61,7 +61,7 @@ def get_var_data(self, fmt=None):
attributes.append('readOnly')
name = '(return) %s' % (name,)

elif name in (TOO_LARGE_ATTR, '__len__'):
elif name in (TOO_LARGE_ATTR, GENERATED_LEN_ATTR_NAME):
attributes.append('readOnly')

var_data = {
Expand Down
6 changes: 3 additions & 3 deletions src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import inspect
import sys
from _pydevd_bundle.pydevd_constants import IS_PY3K, USE_CUSTOM_SYS_CURRENT_FRAMES, IS_PYPY, SUPPORT_GEVENT, \
GEVENT_SUPPORT_NOT_SET_MSG
GEVENT_SUPPORT_NOT_SET_MSG, GENERATED_LEN_ATTR_NAME
from _pydev_imps._pydev_saved_modules import threading


Expand Down Expand Up @@ -76,11 +76,11 @@ def to_number(x):


def compare_object_attrs_key(x):
if '__len__' == x:
if GENERATED_LEN_ATTR_NAME == x:
as_number = to_number(x)
if as_number is None:
as_number = 99999999
# __len__ should appear after other attributes in a list.
# len() should appear after other attributes in a list.
return (1, as_number)
else:
return (-1, to_string(x))
Expand Down
10 changes: 5 additions & 5 deletions src/debugpy/_vendored/pydevd/tests_python/test_debugger_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from _pydevd_bundle.pydevd_comm_constants import file_system_encoding
from _pydevd_bundle.pydevd_constants import (int_types, IS_64BIT_PROCESS,
PY_VERSION_STR, PY_IMPL_VERSION_STR, PY_IMPL_NAME, IS_PY36_OR_GREATER, IS_PY39_OR_GREATER,
IS_PY37_OR_GREATER, IS_PYPY)
IS_PY37_OR_GREATER, IS_PYPY, GENERATED_LEN_ATTR_NAME)
from tests_python import debugger_unittest
from tests_python.debug_constants import TEST_CHERRYPY, IS_PY2, TEST_DJANGO, TEST_FLASK, IS_PY26, \
IS_PY27, IS_CPYTHON, TEST_GEVENT
Expand Down Expand Up @@ -1223,7 +1223,7 @@ def test_dict_ordered(case_setup):

variables_response = json_facade.get_variables_response(ref)
assert [(d['name'], d['value']) for d in variables_response.body.variables if (not d['name'].startswith('_OrderedDict')) and (d['name'] not in DAPGrouper.SCOPES_SORTED)] == [
('4', "'first'"), ('3', "'second'"), ('2', "'last'"), ('__len__', '3')]
('4', "'first'"), ('3', "'second'"), ('2', "'last'"), (GENERATED_LEN_ATTR_NAME, '3')]

json_facade.write_continue()
writer.finished_ok = True
Expand Down Expand Up @@ -1276,7 +1276,7 @@ def test_stack_and_variables_dict(case_setup):
assert check == [
{'name': "'a'", 'value': '30', 'type': 'int', 'evaluateName': "variable_for_test_3['a']", 'variablesReference': 0 },
{'name': "'b'", 'value': '20', 'type': 'int', 'evaluateName': "variable_for_test_3['b']", 'variablesReference': 0},
{'name': '__len__', 'value': '2', 'type': 'int', 'evaluateName': 'len(variable_for_test_3)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}}
{'name': GENERATED_LEN_ATTR_NAME, 'value': '2', 'type': 'int', 'evaluateName': 'len(variable_for_test_3)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}}
]

json_facade.write_continue()
Expand Down Expand Up @@ -1480,7 +1480,7 @@ def test_stack_and_variables_set_and_list(case_setup):
u'variablesReference': 0,
},
{
u'name': u'__len__',
u'name': GENERATED_LEN_ATTR_NAME,
u'type': u'int',
u'value': u'2',
u'evaluateName': u'len(variable_for_test_1)',
Expand Down Expand Up @@ -1683,7 +1683,7 @@ def test_evaluate_variable_references(case_setup):
'variablesReference': 0,
},
{
'name': '__len__',
'name': GENERATED_LEN_ATTR_NAME,
'type': 'int',
'value': '1',
'presentationHint': {'attributes': ['readOnly']},
Expand Down
32 changes: 12 additions & 20 deletions src/debugpy/_vendored/pydevd/tests_python/test_resolvers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from tests_python.debug_constants import IS_PY2
from _pydevd_bundle.pydevd_constants import IS_PY36_OR_GREATER
from _pydevd_bundle.pydevd_constants import IS_PY36_OR_GREATER, GENERATED_LEN_ATTR_NAME


def check_len_entry(len_entry, first_2_params):
Expand All @@ -14,7 +14,7 @@ def test_dict_resolver():
dct = {(1, 2): 2, u'22': 22}
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(dict_resolver.get_contents_debug_adapter_protocol(dct))
len_entry = contents_debug_adapter_protocol.pop(-1)
check_len_entry(len_entry, ('__len__', 2))
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 2))
if IS_PY36_OR_GREATER:
assert contents_debug_adapter_protocol == [
('(1, 2)', 2, '[(1, 2)]'), ("'22'", 22, "['22']")]
Expand All @@ -34,7 +34,7 @@ def test_dict_resolver_hex():
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(
dict_resolver.get_contents_debug_adapter_protocol(dct, fmt={'hex': True}))
len_entry = contents_debug_adapter_protocol.pop(-1)
check_len_entry(len_entry, ('__len__', 1))
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 1))
assert contents_debug_adapter_protocol == [
('(0x1, 0xa, 0x64)', (10000, 100000, 100000), '[(1, 10, 100)]'), ]

Expand Down Expand Up @@ -166,12 +166,6 @@ def __init__(self):
def clear_contents_debug_adapter_protocol(contents_debug_adapter_protocol):
lst = []
for x in contents_debug_adapter_protocol:
if x[0] == '__len__':
if x[2] == '.__len__':
# i.e.: remove a builtin __len__ method, but not the __len__ we add with the length.
continue
lst.append(x)

if not x[0].startswith('__'):

if '<built-in method' in str(x[1]) or '<method-wrapper' in str(x[1]) or '<bound method' in str(x[1]):
Expand All @@ -185,8 +179,6 @@ def clear_contents_debug_adapter_protocol(contents_debug_adapter_protocol):
def clear_contents_dictionary(dictionary):
dictionary = dictionary.copy()
for key in list(dictionary):
if key == '__len__':
continue
if key.startswith('__') or key in ('count', 'index'):
del dictionary[key]
return dictionary
Expand All @@ -213,7 +205,7 @@ def test_tuple_resolver():
('09', 9, '[9]'),
('10', 10, '[10]'),
]
check_len_entry(len_entry, ('__len__', 11))
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 11))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst)) == {
'00': 0,
Expand All @@ -227,7 +219,7 @@ def test_tuple_resolver():
'08': 8,
'09': 9,
'10': 10,
'__len__': 11
GENERATED_LEN_ATTR_NAME: 11
}

lst = tuple(range(17))
Expand All @@ -253,7 +245,7 @@ def test_tuple_resolver():
('0x0f', 15, '[15]'),
('0x10', 16, '[16]'),
]
check_len_entry(len_entry, ('__len__', 17))
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 17))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst, fmt=fmt)) == {
'0x00': 0,
Expand All @@ -273,7 +265,7 @@ def test_tuple_resolver():
'0x0e': 14,
'0x0f': 15,
'0x10': 16,
'__len__': 17
GENERATED_LEN_ATTR_NAME: 17
}

lst = tuple(range(10))
Expand All @@ -291,7 +283,7 @@ def test_tuple_resolver():
('8', 8, '[8]'),
('9', 9, '[9]'),
]
check_len_entry(len_entry, ('__len__', 10))
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 10))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst)) == {
'0': 0,
Expand All @@ -304,7 +296,7 @@ def test_tuple_resolver():
'7': 7,
'8': 8,
'9': 9,
'__len__': 10
GENERATED_LEN_ATTR_NAME: 10
}

contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(tuple_resolver.get_contents_debug_adapter_protocol(lst, fmt=fmt))
Expand All @@ -321,7 +313,7 @@ def test_tuple_resolver():
('0x8', 8, '[8]'),
('0x9', 9, '[9]'),
]
check_len_entry(len_entry, ('__len__', 10))
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 10))

assert clear_contents_dictionary(tuple_resolver.get_dictionary(lst, fmt=fmt)) == {
'0x0': 0,
Expand All @@ -334,7 +326,7 @@ def test_tuple_resolver():
'0x7': 7,
'0x8': 8,
'0x9': 9,
'__len__': 10
GENERATED_LEN_ATTR_NAME: 10
}


Expand All @@ -349,6 +341,6 @@ class CustomTuple(tuple):
my_tuple.some_value = 10
contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(tuple_resolver.get_contents_debug_adapter_protocol(my_tuple))
len_entry = contents_debug_adapter_protocol.pop(-1)
check_len_entry(len_entry, ('__len__', 2))
check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 2))
assert contents_debug_adapter_protocol == [
('some_value', 10, '.some_value'), ('0', 1, '[0]'), ('1', 2, '[1]'), ]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from _pydevd_bundle.pydevd_constants import int_types
from _pydevd_bundle.pydevd_constants import int_types, GENERATED_LEN_ATTR_NAME
from _pydevd_bundle.pydevd_resolver import MAX_ITEMS_TO_HANDLE, TOO_LARGE_ATTR
from _pydevd_bundle import pydevd_frame_utils

Expand Down Expand Up @@ -68,7 +68,7 @@ def test_suspended_frames_manager():
as_dict = (dict([x.get_name(), x.get_var_data()] for x in children_vars if x.get_name() not in DAPGrouper.SCOPES_SORTED))
assert as_dict == {
'0': {'name': '0', 'value': '1', 'type': 'int', 'evaluateName': 'var2[0]', 'variablesReference': 0 },
'__len__': {'name': '__len__', 'value': '1', 'type': 'int', 'evaluateName': 'len(var2)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}, },
GENERATED_LEN_ATTR_NAME: {'name': GENERATED_LEN_ATTR_NAME, 'value': '1', 'type': 'int', 'evaluateName': 'len(var2)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}, },
}

var3 = dict((x.get_name(), x) for x in variable.get_children_variables())['var3']
Expand All @@ -78,7 +78,7 @@ def test_suspended_frames_manager():

check_vars_dict_expected(as_dict, {
'33': {'name': '33', 'value': "[1]", 'type': 'list', 'evaluateName': 'var3[33]'},
'__len__': {'name': '__len__', 'value': '1', 'type': 'int', 'evaluateName': 'len(var3)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}, }
GENERATED_LEN_ATTR_NAME: {'name': GENERATED_LEN_ATTR_NAME, 'value': '1', 'type': 'int', 'evaluateName': 'len(var3)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}, }
})


Expand Down Expand Up @@ -132,11 +132,11 @@ def test_get_child_variables():
var_data = x.get_var_data()
assert 'readOnly' in var_data['presentationHint']['attributes']
found_too_large = True
elif x.name == '__len__':
elif x.name == GENERATED_LEN_ATTR_NAME:
found_len = True

if not found_too_large:
raise AssertionError('Expected to find variable named: %s' % (TOO_LARGE_ATTR,))
if not found_len:
raise AssertionError('Expected to find variable named: __len__')
raise AssertionError('Expected to find variable named: len()')

Loading

0 comments on commit b731a72

Please sign in to comment.