import ast

class ExecutionSandbox:
    def __init__(self):
        self.dangerous_modules = {'os', 'sys', 'subprocess', 'pty', 'shlex', 'shutil'}

    def run_safely(self, code: str) -> dict:
        """Parses the code to ensure dangerous imports are not present, then executes it in an empty globals dict."""
        tree = ast.parse(code)
        
        for node in ast.walk(tree):
            if isinstance(node, ast.Import):
                for alias in node.names:
                    # check for base module (e.g. os.path -> os)
                    base_module = alias.name.split('.')[0]
                    if base_module in self.dangerous_modules:
                        raise ValueError(f"Dangerous import detected: {base_module}")
            elif isinstance(node, ast.ImportFrom):
                if node.module:
                    base_module = node.module.split('.')[0]
                    if base_module in self.dangerous_modules:
                        raise ValueError(f"Dangerous import detected: {base_module}")

        # Execute code in an empty dict globals
        global_env = {}
        local_env = {}
        exec(code, global_env, local_env)
        return local_env
