From 911dee300625bbd6bd3581c98a2b1ab01c269186 Mon Sep 17 00:00:00 2001 From: tristanlatr Date: Mon, 7 Aug 2023 13:17:39 -0400 Subject: [PATCH 1/3] Fix bug in starred assignments #66 --- beniget/beniget.py | 6 +++++- tests/test_chains.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/beniget/beniget.py b/beniget/beniget.py index 50f035b..a30ddc2 100644 --- a/beniget/beniget.py +++ b/beniget/beniget.py @@ -1187,8 +1187,12 @@ 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.Attribute)): self.visit(elt) + elif isinstance(elt, ast.Starred) and isinstance(elt.value, ast.Name): + tmp_store, elt.value.ctx = elt.value.ctx, tmp_store + self.visit(elt) + tmp_store, elt.value.ctx = elt.value.ctx, tmp_store elif isinstance(elt, (ast.List, ast.Tuple)): self.visit_Destructured(elt) return dnode diff --git a/tests/test_chains.py b/tests/test_chains.py index e9d33f8..af35a51 100644 --- a/tests/test_chains.py +++ b/tests/test_chains.py @@ -541,6 +541,41 @@ class Attr(Attr):pass 'Visitor -> ()']) self.assertEqual(c.dump_chains(node.body[-1]), ['Attr -> ()']) + def test_star_assignment(self): + code = ''' +curr, *parts = [1,2,3] +while curr: + print(curr) + if parts: + curr, *parts = parts + else: + break +''' + self.checkChains(code, ['curr -> (curr -> (), curr -> (Call -> ()))', + 'parts -> (Starred -> (), parts -> (), parts -> ())']*2) + + def test_star_assignment_nested(self): + code = ''' +(curr, *parts),i = [1,2,3],0 +while curr: + print(curr) + if parts: + (curr, *parts),i = parts,i + else: + break +''' + self.checkChains(code, ['curr -> (curr -> (), curr -> (Call -> ()))', + 'parts -> (Starred -> (), parts -> (), parts -> (Tuple -> ()))', + 'i -> (i -> (Tuple -> ()))']*2) + + def test_attribute_assignment(self): + code = "d=object();d.name,x = 't',1" + self.checkChains(code, ['d -> (d -> (Attribute -> ()))', + 'x -> ()']) + + def test_call_assignment(self): + code = "NameError().name = 't'" + self.checkChains(code, []) @skipIf(sys.version_info < (3, 0), 'Python 3 syntax') def test_annotation_uses_class_level_name(self): From 28583d60b1adb0baa5a3301e51d9fba253e995e9 Mon Sep 17 00:00:00 2001 From: tristanlatr Date: Mon, 7 Aug 2023 13:52:25 -0400 Subject: [PATCH 2/3] Skip the new tests in python2. --- tests/test_chains.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_chains.py b/tests/test_chains.py index af35a51..5d8e6f9 100644 --- a/tests/test_chains.py +++ b/tests/test_chains.py @@ -540,7 +540,8 @@ class Attr(Attr):pass ['Attr -> (Attr -> (Attr -> ()))', 'Visitor -> ()']) self.assertEqual(c.dump_chains(node.body[-1]), ['Attr -> ()']) - + + @skipIf(sys.version_info < (3, 0), 'Python 3 syntax') def test_star_assignment(self): code = ''' curr, *parts = [1,2,3] @@ -554,6 +555,7 @@ def test_star_assignment(self): self.checkChains(code, ['curr -> (curr -> (), curr -> (Call -> ()))', 'parts -> (Starred -> (), parts -> (), parts -> ())']*2) + @skipIf(sys.version_info < (3, 0), 'Python 3 syntax') def test_star_assignment_nested(self): code = ''' (curr, *parts),i = [1,2,3],0 From a13cf75ea05a468ea47ed83debe76380f7fe9337 Mon Sep 17 00:00:00 2001 From: tristanlatr <19967168+tristanlatr@users.noreply.github.com> Date: Tue, 22 Aug 2023 09:24:55 -0400 Subject: [PATCH 3/3] Starred unpack are not uses of the name they are binding. --- tests/test_chains.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_chains.py b/tests/test_chains.py index 284a179..95e3f04 100644 --- a/tests/test_chains.py +++ b/tests/test_chains.py @@ -574,7 +574,7 @@ def test_star_assignment(self): break ''' self.checkChains(code, ['curr -> (curr -> (), curr -> (Call -> ()))', - 'parts -> (Starred -> (), parts -> (), parts -> ())']*2) + 'parts -> (parts -> (), parts -> ())']*2) @skipIf(sys.version_info < (3, 0), 'Python 3 syntax') def test_star_assignment_nested(self): @@ -588,7 +588,7 @@ def test_star_assignment_nested(self): break ''' self.checkChains(code, ['curr -> (curr -> (), curr -> (Call -> ()))', - 'parts -> (Starred -> (), parts -> (), parts -> (Tuple -> ()))', + 'parts -> (parts -> (), parts -> (Tuple -> ()))', 'i -> (i -> (Tuple -> ()))']*2) def test_attribute_assignment(self):