Make is_definition work on setitem modifications, see #66

This commit is contained in:
Dave Halter
2019-08-25 23:55:15 +02:00
parent 3bb46563d4
commit e8653a49ff
2 changed files with 48 additions and 4 deletions

View File

@@ -210,15 +210,12 @@ class Name(_LeafWithoutNewlines):
""" """
Returns None if there's on definition for a name. Returns None if there's on definition for a name.
:param import_name_alway: Specifies if an import name is always a :param import_name_always: Specifies if an import name is always a
definition. Normally foo in `from foo import bar` is not a definition. Normally foo in `from foo import bar` is not a
definition. definition.
""" """
node = self.parent node = self.parent
type_ = node.type type_ = node.type
if type_ in ('power', 'atom_expr'):
# In `self.x = 3` self is not a definition, but x is.
return None
if type_ in ('funcdef', 'classdef'): if type_ in ('funcdef', 'classdef'):
if self == node.name: if self == node.name:
@@ -1037,6 +1034,14 @@ def _defined_names(current):
trailer = current.children[-1] trailer = current.children[-1]
if trailer.children[0] == '.': if trailer.children[0] == '.':
names.append(trailer.children[1]) names.append(trailer.children[1])
elif trailer.children[0] == '[':
for node in current.children[-2::-1]:
if node.type == 'trailer':
names.append(node.children[1])
break
if node.type == 'name':
names.append(node)
break
else: else:
names.append(current) names.append(current)
return names return names

View File

@@ -180,3 +180,42 @@ def top_function_three():
r = get_raise_stmts(code, 2) # Lists inside try-catch r = get_raise_stmts(code, 2) # Lists inside try-catch
assert len(list(r)) == 2 assert len(list(r)) == 2
@pytest.mark.parametrize(
'code, name_index, is_definition', [
('x = 3', 0, True),
('x.y = 3', 0, False),
('x.y = 3', 1, True),
('x.y = u.v = z', 0, False),
('x.y = u.v = z', 1, True),
('x.y = u.v = z', 2, False),
('x.y = u.v, w = z', 3, True),
('x.y = u.v, w = z', 4, True),
('x.y = u.v, w = z', 5, False),
('x, y = z', 0, True),
('x, y = z', 1, True),
('x, y = z', 2, False),
('x, y = z', 2, False),
('x[0], y = z', 2, False),
('x[0] = z', 0, True),
('x[0], y = z', 0, True),
('x: int = z', 0, True),
('x: int = z', 1, False),
('x: int = z', 2, False),
('x: int', 0, True),
('x: int', 1, False),
]
)
def test_is_definition(code, name_index, is_definition):
module = parse(code, version='3.8')
name = module.get_first_leaf()
while True:
if name.type == 'name':
if name_index == 0:
break
name_index -= 1
name = name.get_next_leaf()
assert name.is_definition() == is_definition