Skip to content

Commit 55fbfb6

Browse files
committed
Fix bug: is_lvalue should check recursively
1 parent f0af419 commit 55fbfb6

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

lambdex/compiler/context.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,5 @@ def assert_name_in(self, clause, names):
141141
self.assert_(clause.name in names, 'expect ' + ' or '.join(names), clause.node)
142142

143143
def assert_lvalue(self, node):
144-
self.assert_(is_lvalue(node), EM_NOT_LVALUE, node)
144+
check_result, failed_at = is_lvalue(node)
145+
self.assert_(check_result, EM_NOT_LVALUE, failed_at)

lambdex/utils/ast.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,21 @@ def copy_lineinfo(src: ast.AST, dst: ast.AST):
123123

124124
def is_lvalue(node: ast.AST) -> bool:
125125
"""
126-
Check whether `node` has field `ctx` (so that it can be used as L-value).
126+
Check whether `node` can be L-value.
127127
"""
128-
return hasattr(node, 'ctx')
128+
from collections import deque
129+
todo = deque([node])
130+
while todo:
131+
n = todo.popleft()
132+
if 'ctx' not in n._fields:
133+
return False, n
134+
if isinstance(n, (ast.List, ast.Tuple, ast.Starred)):
135+
todo.extend(
136+
cn for cn in ast.iter_child_nodes(n) \
137+
if not isinstance(cn, ast.expr_context)
138+
)
139+
140+
return True, None
129141

130142

131143
def cast_to_lvalue(node: ast.AST):

0 commit comments

Comments
 (0)