utils/code_runner/code_runner/harness/harness.py
Krzysztof kuhy Rudnicki 612b0b3c0a Add code_runner sandboxed example runner
Runs a solution (python3, javascript, typescript) against statement
examples in bubblewrap: no network, read-only root, scratch dir,
rlimits and a per-example timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYGW5NZL5uVpnqmNKo
2026-11-02 14:59:30 +01:00

70 lines
2.0 KiB
Python

"""Runs inside the sandbox: call the solution once, write result.json."""
from __future__ import annotations
import json
import os
from pathlib import Path
import sys
import tempfile
import time
from typing import Any
PRELUDE = (
"from typing import *\n"
"import bisect, collections, functools, heapq, itertools, math\n"
"import operator, re, string\n"
)
MAX_MESSAGE = 300
def describe(exc: BaseException) -> str:
return f"{type(exc).__name__}: {exc}"[:MAX_MESSAGE]
def write_result(root: Path, payload: dict[str, object]) -> None:
# Unique name + rename: a symlink the solution planted at result.json is
# replaced by this file, never followed.
handle, name = tempfile.mkstemp(dir=root, prefix=".result-")
with os.fdopen(handle, "w", encoding="utf-8") as out:
json.dump(payload, out)
Path(name).replace(root / "result.json")
def call(root: Path, spec: dict[str, Any]) -> object:
namespace: dict[str, Any] = {"__name__": "solution"}
exec(PRELUDE, namespace)
source = (root / "solution.py").read_text(encoding="utf-8")
exec(compile(source, "solution.py", "exec"), namespace)
owner, name = spec["cls"], str(spec["fn"])
if owner is None:
target = namespace.get(name)
else:
cls = namespace.get(str(owner))
target = getattr(cls() if cls else None, name, None)
if target is None:
message = f"name {owner or name!r} is not defined"
raise NameError(message)
return target(*spec["args"])
def main(directory: str) -> None:
root = Path(directory)
spec = json.loads((root / "input.json").read_text(encoding="utf-8"))
started = time.perf_counter()
try:
value = call(root, spec)
payload: dict[str, object] = {
"ok": True,
"value": json.loads(json.dumps(value)),
}
except BaseException as exc:
payload = {"ok": False, "error": describe(exc)}
payload["ms"] = (time.perf_counter() - started) * 1000
sys.stdout.flush()
write_result(root, payload)
if __name__ == "__main__":
main(sys.argv[1])