Add support for for loops in python interpreter (#24429)

Add support for for loops
This commit is contained in:
Sylvain Gugger
2023-06-26 09:58:14 -04:00
committed by GitHub
parent c2aa5e17e4
commit 5757923888
3 changed files with 23 additions and 0 deletions

View File

@@ -48,6 +48,7 @@ _tools_are_initialized = False
BASE_PYTHON_TOOLS = { BASE_PYTHON_TOOLS = {
"print": print, "print": print,
"range": range,
"float": float, "float": float,
"int": int, "int": int,
"bool": bool, "bool": bool,

View File

@@ -110,6 +110,9 @@ def evaluate_ast(expression: ast.AST, state: Dict[str, Any], tools: Dict[str, Ca
elif isinstance(expression, ast.Expr): elif isinstance(expression, ast.Expr):
# Expression -> evaluate the content # Expression -> evaluate the content
return evaluate_ast(expression.value, state, tools) return evaluate_ast(expression.value, state, tools)
elif isinstance(expression, ast.For):
# For loop -> execute the loop
return evaluate_for(expression, state, tools)
elif isinstance(expression, ast.FormattedValue): elif isinstance(expression, ast.FormattedValue):
# Formatted value (part of f-string) -> evaluate the content and return # Formatted value (part of f-string) -> evaluate the content and return
return evaluate_ast(expression.value, state, tools) return evaluate_ast(expression.value, state, tools)
@@ -236,3 +239,15 @@ def evaluate_if(if_statement, state, tools):
if line_result is not None: if line_result is not None:
result = line_result result = line_result
return result return result
def evaluate_for(for_loop, state, tools):
result = None
iterator = evaluate_ast(for_loop.iter, state, tools)
for counter in iterator:
state[for_loop.target.id] = counter
for expression in for_loop.body:
line_result = evaluate_ast(expression, state, tools)
if line_result is not None:
result = line_result
return result

View File

@@ -122,3 +122,10 @@ class PythonInterpreterTester(unittest.TestCase):
result = evaluate(code, {"add_two": add_two}, state=state) result = evaluate(code, {"add_two": add_two}, state=state)
assert result == 5 assert result == 5
self.assertDictEqual(state, {"x": 3, "test_dict": {"x": 3, "y": 5}}) self.assertDictEqual(state, {"x": 3, "test_dict": {"x": 3, "y": 5}})
def test_evaluate_for(self):
code = "x = 0\nfor i in range(3):\n x = i"
state = {}
result = evaluate(code, {"range": range}, state=state)
assert result == 2
self.assertDictEqual(state, {"x": 2, "i": 2})