Skip to content

Commit ab2a19c

Browse files
committed
added set comprehensions
1 parent 987406d commit ab2a19c

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

custom_components/pyscript/eval.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,29 @@ async def ast_dict(self, arg):
10181018

10191019
async def ast_set(self, arg):
10201020
"""Evaluate set."""
1021-
return {elt for elt in await self.eval_elt_list(arg.elts)} # pylint: disable=unnecessary-comprehension
1021+
return {
1022+
elt for elt in await self.eval_elt_list(arg.elts)
1023+
} # pylint: disable=unnecessary-comprehension
1024+
1025+
async def setcomp_loop(self, generators, elt):
1026+
"""Recursive list comprehension."""
1027+
out = set()
1028+
gen = generators[0]
1029+
for loop_var in await self.aeval(gen.iter):
1030+
await self.recurse_assign(gen.target, loop_var)
1031+
for cond in gen.ifs:
1032+
if not await self.aeval(cond):
1033+
break
1034+
else:
1035+
if len(generators) == 1:
1036+
out.add(await self.aeval(elt))
1037+
else:
1038+
out.update(await self.setcomp_loop(generators[1:], elt))
1039+
return out
1040+
1041+
async def ast_setcomp(self, arg):
1042+
"""Evaluate set comprehension."""
1043+
return await self.setcomp_loop(arg.generators, arg.elt)
10221044

10231045
async def ast_subscript(self, arg):
10241046
"""Evaluate subscript."""

tests/custom_components/pyscript/test_unit_eval.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,33 @@ def no_op(i):
205205
""",
206206
[0, 1, 2, 4, 6, 13],
207207
],
208+
["{i for i in range(7) if i != 5 if i != 3}", {0, 1, 2, 4, 6}],
209+
[
210+
"""
211+
matrix = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
212+
{val for sublist in matrix for val in sublist if val != 8}
213+
""",
214+
{1, 2, 3, 4, 5, 6, 7, 9},
215+
],
216+
[
217+
"""
218+
matrix = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
219+
{val for sublist in matrix if sublist[0] != 4 for val in sublist if val != 8}
220+
""",
221+
{1, 2, 3, 6, 7, 9},
222+
],
223+
[
224+
"""
225+
# check short-circuit of nested if
226+
cnt = 0
227+
def no_op(i):
228+
global cnt
229+
cnt += 1
230+
return i
231+
[{i for i in range(7) if no_op(i) != 5 if no_op(i) != 3}, cnt]
232+
""",
233+
[{0, 1, 2, 4, 6}, 13],
234+
],
208235
[
209236
"""
210237
d = {"x": 1, "y": 2, "z": 3}

0 commit comments

Comments
 (0)