Skip to content

Commit

Permalink
Better support for starred destructuring
Browse files Browse the repository at this point in the history
Previously, x, *y = z was not adding y in the locals / globals
  • Loading branch information
serge-sans-paille committed Aug 22, 2023
1 parent 8f30c16 commit 729f9e5
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
10 changes: 8 additions & 2 deletions beniget/beniget.py
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,13 @@ def visit_Subscript(self, node):
self.visit(node.slice).add_user(dnode)
return dnode

visit_Starred = visit_Await
def visit_Starred(self, node):
if isinstance(node.ctx, ast.Store):
return self.visit(node.value)
else:
dnode = self.chains.setdefault(node, Def(node))
self.visit(node.value).add_user(dnode)
return dnode

def visit_NamedExpr(self, node):
dnode = self.chains.setdefault(node, Def(node))
Expand Down Expand Up @@ -1195,7 +1201,7 @@ def visit_Destructured(self, node):
tmp_store, elt.ctx = elt.ctx, tmp_store
self.visit(elt)
tmp_store, elt.ctx = elt.ctx, tmp_store
elif isinstance(elt, ast.Subscript):
elif isinstance(elt, (ast.Subscript, ast.Starred)):
self.visit(elt)
elif isinstance(elt, (ast.List, ast.Tuple)):
self.visit_Destructured(elt)
Expand Down
5 changes: 5 additions & 0 deletions tests/test_chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ def test_type_destructuring_for(self):
code = "for a, b in ((1,2), (3,4)): a"
self.checkChains(code, ["a -> (a -> ())", "b -> ()"])

if sys.version_info.major >= 3:
def test_type_destructuring_starred(self):
code = "a, *b = range(2); b"
self.checkChains(code, ['a -> ()', 'b -> (b -> ())'])

def test_assign_in_loop(self):
code = "a = 2\nwhile 1: a = 1\na"
self.checkChains(code, ["a -> (a -> ())", "a -> (a -> ())"])
Expand Down
11 changes: 10 additions & 1 deletion tests/test_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ def testGlobalDestructuring(self):
code = "x, y = 1, 2"
self.checkGlobals(code, ["x", "y"])

if sys.version_info.major >= 3:
def testGlobalStarredDestructuring(self):
code = "x, *y = 1, [2]"
self.checkGlobals(code, ["x", "y"])

def testGlobalAugAssign(self):
code = "x = 1; x += 2"
self.checkGlobals(code, ["x"])
Expand Down Expand Up @@ -369,6 +374,10 @@ def test_LocalNonLocalAfter(self):
)
self.checkLocals(code, ["a", "bar"])

def test_LocalDestructuring(self):
code = "def foo(x): y, *z = x"
self.checkLocals(code, ["x", "y", "z"])

def test_LocalMadeGlobal(self):
code = "def foo(): global a; a = 1"
self.checkLocals(code, [])
Expand Down Expand Up @@ -468,4 +477,4 @@ def test_AssignmentSimple(self):
a = a + 1
a = a + 1
"""
self.checkLiveLocals(code, ["a:4"], ["a:2,3,4"])
self.checkLiveLocals(code, ["a:4"], ["a:2,3,4"])

0 comments on commit 729f9e5

Please sign in to comment.