from abc import ABC, abstractmethod
from typing import Any


class OpaqueCallable(ABC):
    """Base class for callables that should appear as single opaque nodes in the graph."""

    @abstractmethod
    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        """Execute the opaque callable with the given arguments."""
        pass

    @property
    @abstractmethod
    def name(self) -> str:
        """Get the name of the opaque callable."""
        pass

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}({self.name})"
