Yago Bolivar commited on
Commit
ada4787
·
1 Parent(s): 0d2816b

fix: enhance output handling and add comprehensive tests for code execution tool

Browse files
Files changed (2) hide show
  1. src/python_tool.py +4 -1
  2. 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
- output = output[:self.max_output_size] + "... [output truncated]"
 
 
 
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()