Yago Bolivar
commited on
Commit
·
ada4787
1
Parent(s):
0d2816b
fix: enhance output handling and add comprehensive tests for code execution tool
Browse files- src/python_tool.py +4 -1
- tests/test_python_tool.py +54 -0
src/python_tool.py
CHANGED
@@ -172,7 +172,10 @@ class CodeExecutionTool:
|
|
172 |
|
173 |
output = output_buffer.getvalue()
|
174 |
if len(output) > self.max_output_size:
|
175 |
-
|
|
|
|
|
|
|
176 |
|
177 |
# Extract the numeric value
|
178 |
numeric_result = self._extract_numeric_value(output)
|
|
|
172 |
|
173 |
output = output_buffer.getvalue()
|
174 |
if len(output) > self.max_output_size:
|
175 |
+
truncation_message = f"\n... [output truncated to {self.max_output_size} characters]"
|
176 |
+
output = output[:self.max_output_size - len(truncation_message)] + truncation_message
|
177 |
+
else:
|
178 |
+
output = output.strip()
|
179 |
|
180 |
# Extract the numeric value
|
181 |
numeric_result = self._extract_numeric_value(output)
|
tests/test_python_tool.py
CHANGED
@@ -40,5 +40,59 @@ class TestCodeExecutionTool(unittest.TestCase):
|
|
40 |
self.assertEqual(reversed_question, "If you understand this sentence, write the opposite of the word \"left\" as the answer.")
|
41 |
self.assertEqual(expected_answer, "Right")
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
if __name__ == "__main__":
|
44 |
unittest.main()
|
|
|
40 |
self.assertEqual(reversed_question, "If you understand this sentence, write the opposite of the word \"left\" as the answer.")
|
41 |
self.assertEqual(expected_answer, "Right")
|
42 |
|
43 |
+
def test_execute_code_success(self):
|
44 |
+
"""Test successful execution of safe Python code."""
|
45 |
+
safe_code = "print(42)"
|
46 |
+
result = self.code_tool.execute_code(safe_code)
|
47 |
+
self.assertTrue(result["success"])
|
48 |
+
self.assertEqual(result["raw_output"].strip(), "42")
|
49 |
+
|
50 |
+
def test_execute_code_numeric_extraction(self):
|
51 |
+
"""Test numeric value extraction from code output."""
|
52 |
+
numeric_code = "print(3.14)"
|
53 |
+
result = self.code_tool.execute_code(numeric_code)
|
54 |
+
self.assertTrue(result["success"])
|
55 |
+
self.assertTrue(result["has_numeric_result"])
|
56 |
+
self.assertEqual(result["numeric_value"], 3.14)
|
57 |
+
|
58 |
+
def test_execute_code_timeout(self):
|
59 |
+
"""Test that code execution times out as expected."""
|
60 |
+
timeout_code = "while True: pass"
|
61 |
+
result = self.code_tool.execute_code(timeout_code)
|
62 |
+
self.assertFalse(result["success"])
|
63 |
+
self.assertIn("timed out", result["error"].lower())
|
64 |
+
|
65 |
+
def test_execute_code_error_handling(self):
|
66 |
+
"""Test error handling for code that raises exceptions."""
|
67 |
+
error_code = "raise ValueError('Test error')"
|
68 |
+
result = self.code_tool.execute_code(error_code)
|
69 |
+
self.assertFalse(result["success"])
|
70 |
+
self.assertIn("ValueError", result["error"])
|
71 |
+
|
72 |
+
def test_execute_code_output_size_limit(self):
|
73 |
+
"""Test that output is truncated if it exceeds max_output_size."""
|
74 |
+
large_output_code = "print('A' * 20000)"
|
75 |
+
result = self.code_tool.execute_code(large_output_code)
|
76 |
+
self.assertTrue(result["success"])
|
77 |
+
self.assertLessEqual(len(result["raw_output"]), self.code_tool.max_output_size)
|
78 |
+
|
79 |
+
def test_execute_file_success(self):
|
80 |
+
"""Test successful execution of a Python file."""
|
81 |
+
test_file_path = "test_script.py"
|
82 |
+
with open(test_file_path, "w") as f:
|
83 |
+
f.write("print('File executed successfully')")
|
84 |
+
|
85 |
+
result = self.code_tool.execute_file(test_file_path)
|
86 |
+
self.assertTrue(result["success"])
|
87 |
+
self.assertEqual(result["raw_output"].strip(), "File executed successfully")
|
88 |
+
|
89 |
+
os.remove(test_file_path)
|
90 |
+
|
91 |
+
def test_execute_file_not_found(self):
|
92 |
+
"""Test handling of file not found error."""
|
93 |
+
result = self.code_tool.execute_file("non_existent_file.py")
|
94 |
+
self.assertFalse(result["success"])
|
95 |
+
self.assertIn("File not found", result["error"])
|
96 |
+
|
97 |
if __name__ == "__main__":
|
98 |
unittest.main()
|