diff --git a/src/smolagents/local_python_executor.py b/src/smolagents/local_python_executor.py index e2df293..a48e1e1 100644 --- a/src/smolagents/local_python_executor.py +++ b/src/smolagents/local_python_executor.py @@ -1229,8 +1229,14 @@ def evaluate_ast( # For loop -> execute the loop return evaluate_for(expression, *common_params) elif isinstance(expression, ast.FormattedValue): - # Formatted value (part of f-string) -> evaluate the content and return - return evaluate_ast(expression.value, *common_params) + # Formatted value (part of f-string) -> evaluate the content and format it + value = evaluate_ast(expression.value, *common_params) + # Early return if no format spec + if not expression.format_spec: + return value + # Apply format specification + format_spec = evaluate_ast(expression.format_spec, *common_params) + return format(value, format_spec) elif isinstance(expression, ast.If): # If -> execute the right branch return evaluate_if(expression, *common_params) diff --git a/tests/test_local_python_executor.py b/tests/test_local_python_executor.py index 7777631..29e1ec9 100644 --- a/tests/test_local_python_executor.py +++ b/tests/test_local_python_executor.py @@ -122,6 +122,22 @@ class PythonInterpreterTester(unittest.TestCase): assert result == "This is x: 3." self.assertDictEqualNoPrint(state, {"x": 3, "text": "This is x: 3.", "_operations_count": 6}) + def test_evaluate_f_string_with_format(self): + code = "text = f'This is x: {x:.2f}.'" + state = {"x": 3.336} + result, _ = evaluate_python_code(code, {}, state=state) + assert result == "This is x: 3.34." + self.assertDictEqualNoPrint(state, {"x": 3.336, "text": "This is x: 3.34.", "_operations_count": 8}) + + def test_evaluate_f_string_with_complex_format(self): + code = "text = f'This is x: {x:>{width}.{precision}f}.'" + state = {"x": 3.336, "width": 10, "precision": 2} + result, _ = evaluate_python_code(code, {}, state=state) + assert result == "This is x: 3.34." + self.assertDictEqualNoPrint( + state, {"x": 3.336, "width": 10, "precision": 2, "text": "This is x: 3.34.", "_operations_count": 14} + ) + def test_evaluate_if(self): code = "if x <= 3:\n y = 2\nelse:\n y = 5" state = {"x": 3}