Spaces:
Sleeping
Sleeping
| import subprocess | |
| import time | |
| import os | |
| import tempfile | |
| import ast | |
| from .models import ExecutionResult | |
| def run_code_with_tests(code: str, test_code: str, timeout: float = 5.0) -> ExecutionResult: | |
| # Syntax check | |
| try: | |
| ast.parse(code) | |
| except SyntaxError as e: | |
| return ExecutionResult( | |
| compile_success=False, | |
| runtime_errors=str(e), | |
| test_passed=0, | |
| test_total=0, | |
| execution_time_seconds=0.0, | |
| success=False | |
| ) | |
| # Combine code and test definitions | |
| full_code = f""" | |
| import sys | |
| import unittest | |
| import time | |
| import io | |
| {code} | |
| {test_code} | |
| if __name__ == '__main__': | |
| stream = io.StringIO() | |
| runner = unittest.TextTestRunner(stream=stream, verbosity=2) | |
| start_time = time.time() | |
| result = runner.run(unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__])) | |
| end_time = time.time() | |
| output = stream.getvalue() | |
| print(f"|CODEARENA_STATS|{{result.wasSuccessful()}}|{{result.testsRun - len(result.failures) - len(result.errors)}}|{{result.testsRun}}|{{end_time - start_time}}|") | |
| if not result.wasSuccessful(): | |
| print(output) | |
| """ | |
| with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f: | |
| f.write(full_code) | |
| temp_file = f.name | |
| start_wall = time.time() | |
| try: | |
| process = subprocess.run( | |
| ['python', temp_file], | |
| capture_output=True, | |
| text=True, | |
| timeout=timeout | |
| ) | |
| wall_time = time.time() - start_wall | |
| stdout = process.stdout | |
| stderr = process.stderr | |
| stats_line = None | |
| for line in stdout.split('\n'): | |
| if line.startswith('|CODEARENA_STATS|'): | |
| stats_line = line | |
| break | |
| if stats_line: | |
| parts = stats_line.split('|') | |
| success_str = parts[2] | |
| passed = int(parts[3]) | |
| total = int(parts[4]) | |
| exec_time = float(parts[5]) | |
| return ExecutionResult( | |
| compile_success=True, | |
| runtime_errors=stderr if stderr else "", | |
| test_passed=passed, | |
| test_total=total, | |
| execution_time_seconds=exec_time, | |
| success=(success_str == 'True') | |
| ) | |
| else: | |
| return ExecutionResult( | |
| compile_success=True, | |
| runtime_errors="Tests did not complete successfully or output was malformed. Stderr: " + stderr + "\nStdout: " + stdout, | |
| test_passed=0, | |
| test_total=1, # Assume at least 1 failed | |
| execution_time_seconds=wall_time, | |
| success=False | |
| ) | |
| except subprocess.TimeoutExpired as e: | |
| return ExecutionResult( | |
| compile_success=True, | |
| runtime_errors="Execution timed out.", | |
| test_passed=0, | |
| test_total=1, | |
| execution_time_seconds=timeout, | |
| success=False | |
| ) | |
| finally: | |
| if os.path.exists(temp_file): | |
| os.remove(temp_file) | |