From b6e5b6c274ac0673c411fa635d442b2f30b19226 Mon Sep 17 00:00:00 2001 From: Alex Konradi Date: Sun, 15 Oct 2023 07:20:58 -0400 Subject: [PATCH] Ignore failure to delete list comp variables When iterating over a generator expression `gen` in a list comprehension `[for x in gen]`, the local variable `x` holds the value of each generated expression. When the list comprehension is done being evaluated, the local variable `x` needs to be deleted. This was already being done. If, however, `gen` is empty, `x` is never defined, and so deleting it causes an error. This patch adds a check to ignore that error. --- custom_components/pyscript/eval.py | 7 ++++++- tests/test_unit_eval.py | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/custom_components/pyscript/eval.py b/custom_components/pyscript/eval.py index f13ee54..53e44fb 100644 --- a/custom_components/pyscript/eval.py +++ b/custom_components/pyscript/eval.py @@ -1753,7 +1753,12 @@ async def loopvar_scope_restore(self, var_names, save_vars): if var_name in save_vars: self.sym_table[var_name] = save_vars[var_name] else: - del self.sym_table[var_name] + try: + del self.sym_table[var_name] + except KeyError: + # If the iterator was empty, the loop variables were never + # assigned to, so deleting them will fail. + pass async def listcomp_loop(self, generators, elt): """Recursive list comprehension.""" diff --git a/tests/test_unit_eval.py b/tests/test_unit_eval.py index 4f8037d..21cbc22 100644 --- a/tests/test_unit_eval.py +++ b/tests/test_unit_eval.py @@ -81,6 +81,8 @@ ["kw = {'x': 1, 'y': 5}; kw2 = {'z': 10}; {**kw, **kw2}", {"x": 1, "y": 5, "z": 10}], ["[*iter([1, 2, 3])]", [1, 2, 3]], ["{*iter([1, 2, 3])}", {1, 2, 3}], + ["[x for x in []]", []], + ["[x for x in [] if x]", []], ["if 1: x = 10\nelse: x = 20\nx", 10], ["if 0: x = 10\nelse: x = 20\nx", 20], ["i = 0\nwhile i < 5: i += 1\ni", 5],