Skip to content

Commit 166e90f

Browse files
authored
Merge pull request #150 from danthedeckie/dictcomp-support
Dictcomp support (rebased #133)
2 parents ccb584e + c9dcca1 commit 166e90f

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

Diff for: simpleeval.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
- edgarrmondragon (Edgar Ramírez-Mondragón) Address Python 3.12+ deprecation warnings
6363
- cedk (Cédric Krier) <ced@b2ck.com> Allow running tests with Werror
6464
- decorator-factory <decorator-factory@protonmail.com> More security fixes
65+
- lkruitwagen (Lucas Kruitwagen) Adding support for dict comprehensions
6566
6667
-------------------------------------
6768
Basic Usage:
@@ -661,6 +662,7 @@ def __init__(self, operators=None, functions=None, names=None):
661662
ast.Set: self._eval_set,
662663
ast.ListComp: self._eval_comprehension,
663664
ast.GeneratorExp: self._eval_comprehension,
665+
ast.DictComp: self._eval_comprehension,
664666
}
665667
)
666668

@@ -699,7 +701,10 @@ def _eval_set(self, node):
699701
return set(self._eval(x) for x in node.elts)
700702

701703
def _eval_comprehension(self, node):
702-
to_return = []
704+
if isinstance(node, ast.DictComp):
705+
to_return = {}
706+
else:
707+
to_return = []
703708

704709
extra_names = {}
705710

@@ -738,7 +743,10 @@ def do_generator(gi=0):
738743
if len(node.generators) > gi + 1:
739744
do_generator(gi + 1)
740745
else:
741-
to_return.append(self._eval(node.elt))
746+
if isinstance(to_return, dict):
747+
to_return[self._eval(node.key)] = self._eval(node.value)
748+
elif isinstance(to_return, list):
749+
to_return.append(self._eval(node.elt))
742750

743751
try:
744752
do_generator()

Diff for: test_simpleeval.py

+18
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,24 @@ def test_unpack(self):
729729
def test_nested_unpack(self):
730730
self.t("[a+b+c for a, (b, c) in ((1,(1,1)),(3,(2,2)))]", [3, 7])
731731

732+
def test_dictcomp_basic(self):
733+
self.t("{a:a + 1 for a in [1,2,3]}", {1: 2, 2: 3, 3: 4})
734+
735+
def test_dictcomp_with_self_reference(self):
736+
self.t("{a:a + a for a in [1,2,3]}", {1: 2, 2: 4, 3: 6})
737+
738+
def test_dictcomp_with_if(self):
739+
self.t("{a:a for a in [1,2,3,4,5] if a <= 3}", {1: 1, 2: 2, 3: 3})
740+
741+
def test_dictcomp_with_multiple_if(self):
742+
self.t("{a:a for a in [1,2,3,4,5] if a <= 3 and a > 1 }", {2: 2, 3: 3})
743+
744+
def test_dictcomp_unpack(self):
745+
self.t("{a:a+b for a,b in ((1,2),(3,4))}", {1: 3, 3: 7})
746+
747+
def test_dictcomp_nested_unpack(self):
748+
self.t("{a:a+b+c for a, (b, c) in ((1,(1,1)),(3,(2,2)))}", {1: 3, 3: 7})
749+
732750
def test_other_places(self):
733751
self.s.functions = {"sum": sum}
734752
self.t("sum([a+1 for a in [1,2,3,4,5]])", 20)

0 commit comments

Comments
 (0)