Navya-Sree commited on
Commit
9fb804e
·
verified ·
1 Parent(s): 8b7a207

Create src/macg/tools/python_runner.py

Browse files
Files changed (1) hide show
  1. src/macg/tools/python_runner.py +42 -0
src/macg/tools/python_runner.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ import os
3
+ import subprocess
4
+ import tempfile
5
+ from dataclasses import dataclass
6
+
7
+ @dataclass
8
+ class RunResult:
9
+ ok: bool
10
+ stdout: str
11
+ stderr: str
12
+ returncode: int
13
+
14
+ def run_pytest(module_name: str, code: str, tests: str, timeout_s: int = 15) -> RunResult:
15
+ """
16
+ Minimal safety:
17
+ - runs in temp dir
18
+ - timeout
19
+ NOTE: still executes arbitrary code. For “serious” safety, use containers/sandboxing.
20
+ """
21
+ with tempfile.TemporaryDirectory() as d:
22
+ mod_path = os.path.join(d, f"{module_name}.py")
23
+ test_path = os.path.join(d, "test_solution.py")
24
+ with open(mod_path, "w", encoding="utf-8") as f:
25
+ f.write(code)
26
+ with open(test_path, "w", encoding="utf-8") as f:
27
+ f.write(tests)
28
+
29
+ cmd = ["python", "-m", "pytest", "-q"]
30
+ try:
31
+ p = subprocess.run(
32
+ cmd,
33
+ cwd=d,
34
+ capture_output=True,
35
+ text=True,
36
+ timeout=timeout_s,
37
+ env={**os.environ, "PYTHONPATH": d},
38
+ )
39
+ ok = (p.returncode == 0)
40
+ return RunResult(ok=ok, stdout=p.stdout, stderr=p.stderr, returncode=p.returncode)
41
+ except subprocess.TimeoutExpired as e:
42
+ return RunResult(ok=False, stdout=e.stdout or "", stderr="Timeout running pytest.", returncode=124)