from __future__ import annotations import os import stat import sys from pathlib import Path from types import SimpleNamespace import pytest from opensquilla.sandbox import sensitive_paths from opensquilla.tools.builtin import code_exec from opensquilla.tools.types import ToolContext, current_tool_context def test_code_exec_prefers_current_interpreter_when_path_has_no_python( monkeypatch: pytest.MonkeyPatch, tmp_path: Path ) -> None: python_bin = tmp_path / ("python.exe" if os.name == "nt" else "python") python_bin.write_text("", encoding="utf-8") python_bin.chmod(python_bin.stat().st_mode | stat.S_IXUSR) monkeypatch.setattr(sys, "executable", str(python_bin)) monkeypatch.setattr(code_exec.shutil, "which", lambda _name: None) assert code_exec._resolve_python_bin(sandbox_enabled=False) == str(python_bin) def test_code_exec_prefers_current_interpreter_for_non_bubblewrap_sandbox( monkeypatch: pytest.MonkeyPatch, tmp_path: Path ) -> None: python_bin = tmp_path / ("python.exe" if os.name == "nt" else "python") python_bin.write_text("", encoding="utf-8") python_bin.chmod(python_bin.stat().st_mode | stat.S_IXUSR) monkeypatch.setattr(sys, "executable", str(python_bin)) monkeypatch.setattr(code_exec.shutil, "which", lambda _name: None) monkeypatch.setattr( code_exec, "get_runtime", lambda: SimpleNamespace(backend=SimpleNamespace(name="noop")), ) assert code_exec._resolve_python_bin(sandbox_enabled=True) == str(python_bin) def test_code_exec_bubblewrap_sandbox_prefers_visible_system_python( monkeypatch: pytest.MonkeyPatch, tmp_path: Path ) -> None: host_python = tmp_path / ("venv-python.exe" if os.name == "nt" else "venv-python") sandbox_python = tmp_path / ("python3.exe" if os.name == "nt" else "python3") host_python.write_text("", encoding="utf-8") sandbox_python.write_text("", encoding="utf-8") host_python.chmod(host_python.stat().st_mode | stat.S_IXUSR) sandbox_python.chmod(sandbox_python.stat().st_mode | stat.S_IXUSR) monkeypatch.setattr(sys, "executable", str(host_python)) monkeypatch.setattr(code_exec.shutil, "which", lambda _name: None) monkeypatch.setattr(code_exec, "_SANDBOX_PYTHON_CANDIDATES", (sandbox_python,)) monkeypatch.setattr( code_exec, "get_runtime", lambda: SimpleNamespace(backend=SimpleNamespace(name="bubblewrap")), ) assert code_exec._resolve_python_bin(sandbox_enabled=True) == str(sandbox_python) def test_code_exec_allows_active_workspace_under_sensitive_parent( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, ) -> None: workspace = tmp_path / "workspace" workspace.mkdir() monkeypatch.setattr(sensitive_paths, "_SENSITIVE_PREFIXES", (str(tmp_path),)) monkeypatch.setattr( sensitive_paths, "_WORKSPACE_PARENT_EXCEPTION_MARKERS", (str(tmp_path),), ) token = current_tool_context.set(ToolContext(workspace_dir=str(workspace))) try: result = code_exec._check_code_sensitive_access( f"from pathlib import Path\nprint(Path({str(workspace / 'data.txt')!r}).read_text())" ) finally: current_tool_context.reset(token) assert result is None def test_code_exec_workspace_exception_keeps_leaf_secret_blocks( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, ) -> None: workspace = tmp_path / "workspace" workspace.mkdir() monkeypatch.setattr(sensitive_paths, "_SENSITIVE_PREFIXES", (str(tmp_path),)) monkeypatch.setattr( sensitive_paths, "_WORKSPACE_PARENT_EXCEPTION_MARKERS", (str(tmp_path),), ) token = current_tool_context.set(ToolContext(workspace_dir=str(workspace))) try: result = code_exec._check_code_sensitive_access( f"open({str(workspace / '.env')!r}).read()" ) finally: current_tool_context.reset(token) assert result is not None assert result[0] == "sensitive_path"