From 8c77811d701e8c8d58a82f62acd8e08d9bfd7048 Mon Sep 17 00:00:00 2001 From: Jimmy Lai Date: Tue, 4 Feb 2020 17:18:31 -0800 Subject: [PATCH] [metadata][QualifiedNameProvider] don't provide qualified name for names in Attribute().attr --- libcst/metadata/scope_provider.py | 4 ++++ .../tests/test_qualified_name_provider.py | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/libcst/metadata/scope_provider.py b/libcst/metadata/scope_provider.py index 01fef7c1..794acd97 100644 --- a/libcst/metadata/scope_provider.py +++ b/libcst/metadata/scope_provider.py @@ -619,6 +619,10 @@ class ScopeVisitor(cst.CSTVisitor): def visit_ImportFrom(self, node: cst.ImportFrom) -> Optional[bool]: return self._visit_import_alike(node) + def visit_Attribute(self, node: cst.Attribute) -> Optional[bool]: + node.value.visit(self) # explicitly not visiting attr + return False + def visit_Name(self, node: cst.Name) -> Optional[bool]: # not all Name have ExpressionContext context = self.provider.get_metadata(ExpressionContextProvider, node, None) diff --git a/libcst/metadata/tests/test_qualified_name_provider.py b/libcst/metadata/tests/test_qualified_name_provider.py index d2a0e6fa..5bb158f2 100644 --- a/libcst/metadata/tests/test_qualified_name_provider.py +++ b/libcst/metadata/tests/test_qualified_name_provider.py @@ -244,3 +244,23 @@ class ScopeProviderTest(UnitTest): ) MetadataWrapper(cst.parse_module("import a;a.b.c()")).visit(TestVisitor(self)) + + def test_name_in_attribute(self) -> None: + m, names = get_qualified_name_metadata_provider( + """ + obj = object() + obj.eval + """ + ) + attr = ensure_type( + ensure_type( + ensure_type(m.body[1], cst.SimpleStatementLine).body[0], cst.Expr + ).value, + cst.Attribute, + ) + self.assertEqual( + names[attr], + {QualifiedName(name="obj.eval", source=QualifiedNameSource.LOCAL)}, + ) + eval = attr.attr + self.assertEqual(names[eval], set())