Optimize Scope Analysis memory usage by removing unnecessary Assignment creation

This commit is contained in:
Jimmy Lai 2020-02-27 20:55:41 -08:00 committed by jimmylai
parent bd31d3feac
commit 8136f10e2e
2 changed files with 24 additions and 4 deletions

View file

@ -36,6 +36,8 @@ from libcst.metadata.expression_context_provider import (
)
@add_slots
@dataclass(frozen=False)
class Access:
"""
An Access records an access of an assignment.
@ -698,10 +700,19 @@ class ScopeVisitor(cst.CSTVisitor):
attr.visit(self)
return False
def visit_Arg_keyword(self, node: cst.Arg) -> None:
keyword = node.keyword
if keyword is not None:
self.scope.record_assignment(keyword.value, node)
def visit_Arg(self, node: cst.Arg) -> Optional[bool]:
# The keyword of Arg is neither an Assignment nor an Access and we explicitly don't visit it.
for attr in [
node.value,
node.equal,
node.comma,
node.star,
node.whitespace_after_star,
node.whitespace_after_arg,
]:
if isinstance(attr, cst.CSTNode):
attr.visit(self)
return False
def visit_ClassDef(self, node: cst.ClassDef) -> Optional[bool]:
self.scope.record_assignment(node.name.value, node)

View file

@ -987,3 +987,12 @@ class ScopeProviderTest(UnitTest):
{ensure_type(del_a_b.target, cst.Attribute).value},
)
self.assertEqual(scope["b"], ())
def test_keyword_arg_in_call(self) -> None:
m, scopes = get_scope_metadata_provider("call(arg=val)")
call = ensure_type(
ensure_type(m.body[0], cst.SimpleStatementLine).body[0], cst.Expr
).value
scope = scopes[call]
self.assertIsInstance(scope, GlobalScope)
self.assertEqual(len(scope["arg"]), 0) # no assignment should exist