Test evaluate_delete (#519)

This commit is contained in:
Albert Villanova del Moral 2025-02-11 11:06:31 +01:00 committed by GitHub
parent af665c300c
commit 8c6f90cc11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 68 additions and 3 deletions

View File

@ -1379,12 +1379,11 @@ def evaluate_python_code(
is_final_answer = True is_final_answer = True
return e.value, is_final_answer return e.value, is_final_answer
except Exception as e: except Exception as e:
exception_type = type(e).__name__
state["_print_outputs"].value = truncate_content( state["_print_outputs"].value = truncate_content(
str(state["_print_outputs"]), max_length=max_print_outputs_length str(state["_print_outputs"]), max_length=max_print_outputs_length
) )
raise InterpreterError( raise InterpreterError(
f"Code execution failed at line '{ast.get_source_segment(code, node)}' due to: {exception_type}:{str(e)}" f"Code execution failed at line '{ast.get_source_segment(code, node)}' due to: {type(e).__name__}: {e}"
) )

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import ast
import types import types
import unittest import unittest
from textwrap import dedent from textwrap import dedent
@ -24,6 +25,7 @@ from smolagents.default_tools import BASE_PYTHON_TOOLS
from smolagents.local_python_executor import ( from smolagents.local_python_executor import (
InterpreterError, InterpreterError,
PrintContainer, PrintContainer,
evaluate_delete,
evaluate_python_code, evaluate_python_code,
fix_final_answer_code, fix_final_answer_code,
get_safe_module, get_safe_module,
@ -1090,6 +1092,70 @@ def test_evaluate_augassign_custom(operator, expected_result):
assert result == expected_result assert result == expected_result
@pytest.mark.parametrize(
"code, expected_error_message",
[
(
dedent("""\
x = 5
del x
x
"""),
"The variable `x` is not defined",
),
(
dedent("""\
x = [1, 2, 3]
del x[2]
x[2]
"""),
"Index 2 out of bounds for list of length 2",
),
(
dedent("""\
x = {"key": "value"}
del x["key"]
x["key"]
"""),
"Could not index {} with 'key'",
),
(
dedent("""\
del x
"""),
"Cannot delete name 'x': name is not defined",
),
],
)
def test_evaluate_python_code_with_evaluate_delete(code, expected_error_message):
state = {}
with pytest.raises(InterpreterError) as exception_info:
evaluate_python_code(code, {}, state=state)
assert expected_error_message in str(exception_info.value)
@pytest.mark.parametrize(
"code, state, expectation",
[
("del x", {"x": 1}, {}),
("del x[1]", {"x": [1, 2, 3]}, {"x": [1, 3]}),
("del x['key']", {"x": {"key": "value"}}, {"x": {}}),
("del x", {}, InterpreterError("Cannot delete name 'x': name is not defined")),
],
)
def test_evaluate_delete(code, state, expectation):
state["_operations_count"] = 0
delete_node = ast.parse(code).body[0]
if isinstance(expectation, Exception):
with pytest.raises(type(expectation)) as exception_info:
evaluate_delete(delete_node, state, {}, {}, [])
assert str(expectation) in str(exception_info.value)
else:
evaluate_delete(delete_node, state, {}, {}, [])
del state["_operations_count"]
assert state == expectation
def test_get_safe_module_handle_lazy_imports(): def test_get_safe_module_handle_lazy_imports():
class FakeModule(types.ModuleType): class FakeModule(types.ModuleType):
def __init__(self, name): def __init__(self, name):