diff --git a/CHANGELOG.md b/CHANGELOG.md index 30f4751..c364fee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Removed + +- **Dead Executor Methods** — remove `Executor.execute_parallel()` and `Executor.execute_sequential()`, which had no production callers (the pipeline uses `Executor.gather()`); their only in-tree references were two dedicated unit tests (#52) + --- ## [0.4.8] - 2026-07-24 diff --git a/openagent_eval/core/executor.py b/openagent_eval/core/executor.py index 44ee0f1..93560c6 100644 --- a/openagent_eval/core/executor.py +++ b/openagent_eval/core/executor.py @@ -4,7 +4,7 @@ import asyncio from concurrent.futures import ThreadPoolExecutor -from typing import Any, Callable, Coroutine +from typing import Any, Callable from openagent_eval.exceptions import MetricExecutionError @@ -28,48 +28,6 @@ def __init__(self, max_workers: int = 4, timeout: float = 300.0) -> None: self._semaphore = asyncio.Semaphore(max_workers) self._thread_pool: ThreadPoolExecutor | None = None - async def execute_parallel( - self, - tasks: list[Callable[..., Coroutine[Any, Any, Any]]], - *args: Any, - **kwargs: Any, - ) -> list[Any]: - """Execute multiple tasks in parallel with concurrency limits. - - Args: - tasks: List of async functions to execute. - *args: Positional arguments to pass to each task. - **kwargs: Keyword arguments to pass to each task. - - Returns: - List of results from each task. - - Raises: - MetricExecutionError: If a task fails or times out. - """ - async def _run_with_semaphore( - task: Callable[..., Coroutine[Any, Any, Any]], - ) -> Any: - async with self._semaphore: - try: - return await asyncio.wait_for( - task(*args, **kwargs), - timeout=self.timeout, - ) - except asyncio.TimeoutError: - raise MetricExecutionError( - message=f"Task timed out after {self.timeout}s", - details={"timeout": self.timeout}, - ) - except Exception as e: - raise MetricExecutionError( - message=f"Task failed: {e}", - original_error=e, - ) from e - - coroutines = [_run_with_semaphore(task) for task in tasks] - return await asyncio.gather(*coroutines) - async def gather(self, coroutines: list[Any]) -> list[Any]: """Run coroutines concurrently with the configured concurrency limit. @@ -104,45 +62,6 @@ async def _run(coro: Any) -> Any: return [t.result() for t in tasks] - async def execute_sequential( - self, - tasks: list[Callable[..., Coroutine[Any, Any, Any]]], - *args: Any, - **kwargs: Any, - ) -> list[Any]: - """Execute tasks sequentially. - - Args: - tasks: List of async functions to execute. - *args: Positional arguments to pass to each task. - **kwargs: Keyword arguments to pass to each task. - - Returns: - List of results from each task. - - Raises: - MetricExecutionError: If a task fails. - """ - results: list[Any] = [] - for task in tasks: - try: - result = await asyncio.wait_for( - task(*args, **kwargs), - timeout=self.timeout, - ) - results.append(result) - except asyncio.TimeoutError: - raise MetricExecutionError( - message=f"Task timed out after {self.timeout}s", - details={"timeout": self.timeout}, - ) - except Exception as e: - raise MetricExecutionError( - message=f"Task failed: {e}", - original_error=e, - ) from e - return results - async def run_in_thread( self, func: Callable[..., Any], diff --git a/tests/unit/test_core/test_engine.py b/tests/unit/test_core/test_engine.py index 2de1971..6dd7bf8 100644 --- a/tests/unit/test_core/test_engine.py +++ b/tests/unit/test_core/test_engine.py @@ -68,28 +68,6 @@ def test_init(self) -> None: assert executor.max_workers == 2 assert executor.timeout == 60.0 - @pytest.mark.asyncio - async def test_execute_parallel(self) -> None: - """Test parallel execution.""" - executor = Executor(max_workers=2) - - async def fake_task(x: int) -> int: - return x * 2 - - results = await executor.execute_parallel([fake_task, fake_task], 5) - assert results == [10, 10] - - @pytest.mark.asyncio - async def test_execute_sequential(self) -> None: - """Test sequential execution.""" - executor = Executor(max_workers=2) - - async def fake_task(x: int) -> int: - return x * 2 - - results = await executor.execute_sequential([fake_task, fake_task], 5) - assert results == [10, 10] - class TestPipeline: """Tests for the evaluation pipeline."""