diff --git a/parso/python/tree.py b/parso/python/tree.py index 7d4a490..3d5e842 100644 --- a/parso/python/tree.py +++ b/parso/python/tree.py @@ -210,15 +210,12 @@ class Name(_LeafWithoutNewlines): """ 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. """ node = self.parent 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 self == node.name: @@ -1037,6 +1034,14 @@ def _defined_names(current): trailer = current.children[-1] if trailer.children[0] == '.': 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: names.append(current) return names diff --git a/test/test_parser_tree.py b/test/test_parser_tree.py index 69cfe76..d9d5893 100644 --- a/test/test_parser_tree.py +++ b/test/test_parser_tree.py @@ -180,3 +180,42 @@ def top_function_three(): r = get_raise_stmts(code, 2) # Lists inside try-catch 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