from __future__ import annotations
from pathlib import Path
from typing import Iterable

import re

def is_secure_path(target_file: str | Path, allowed_dirs: Iterable[str | Path]) -> bool:
    """
    Verifies if a target path resides within an allowed sandbox directory.
    Uses path resolution to prevent traversal attacks.
    
    Args:
        target_file: The path to verify.
        allowed_dirs: A collection of directories where access is permitted.
        
    Returns:
        bool: True if the path is secure, False otherwise.
    """
    try:
        target_path = Path(target_file).resolve()
        for allowed in allowed_dirs:
            allowed_path = Path(allowed).resolve()
            # is_relative_to is available in Python 3.9+
            if target_path.is_relative_to(allowed_path):
                return True
    except (ValueError, RuntimeError, OSError):
        return False
    return False

def is_valid_identifier(name: str) -> bool:
    """
    Checks if a string is a valid Python identifier.
    Prevents code injection in code generation.
    """
    return bool(re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', name))

def is_valid_module_path(module_path: str) -> bool:
    """
    Checks if a string is a valid Python module path (e.g. 'a.b.c').
    """
    return all(is_valid_identifier(part) for part in module_path.split('.'))
