diff --git a/CHANGES b/CHANGES index 4be978a..d04815d 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,12 @@ _Notes on upcoming releases will be added here_ +### Development + +**Minimum `pytest>=9.1.0`** + +The dev and test dependency groups now require pytest 9.1.0 or newer. (#83) + ## libtmux-mcp 0.1.0a14 (2026-06-14) libtmux-mcp 0.1.0a14 adds tier-aware tool batching. {tooliconl}`call-readonly-tools-batch`, {tooliconl}`call-mutating-tools-batch`, and {tooliconl}`call-destructive-tools-batch` run an ordered list of existing MCP tools in a single call and return a per-operation result for each, preserving every nested tool's own structured output. Each wrapper caps the safety tier of the calls it will make — regardless of the server's `LIBTMUX_SAFETY` tier — and `on_error` selects stop-at-first-failure or continue-and-report handling. Aggregate results stay within the server's response limit. diff --git a/pyproject.toml b/pyproject.toml index 094f714..eaf75eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ dev = [ # Testing "typing-extensions; python_version < '3.11'", "gp-libs", - "pytest", + "pytest>=9.1.0", # >=9.1.0 attaches caplog to non-propagating loggers; see test_middleware "pytest-rerunfailures", "pytest-mock", "pytest-watcher", @@ -91,7 +91,7 @@ docs = [ testing = [ "typing-extensions; python_version < '3.11'", "gp-libs", - "pytest", + "pytest>=9.1.0", # >=9.1.0 attaches caplog to non-propagating loggers; see test_middleware "pytest-rerunfailures", "pytest-mock", "pytest-watcher", diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 698db81..0a42a3d 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -448,7 +448,6 @@ def test_send_keys_batch_schema_validation_redacts_inputs( secret: str, expected_fragments: tuple[str, ...], caplog: pytest.LogCaptureFixture, - monkeypatch: pytest.MonkeyPatch, ) -> None: """Malformed batch schema errors do not echo raw key payloads.""" from fastmcp import Client @@ -456,8 +455,6 @@ def test_send_keys_batch_schema_validation_redacts_inputs( from libtmux_mcp.server import build_mcp_server assert test_id - for logger_name in ("fastmcp", "fastmcp.server.server", "fastmcp.errors"): - monkeypatch.setattr(logging.getLogger(logger_name), "propagate", True) async def _call() -> t.Any: async with Client(build_mcp_server()) as client: @@ -1109,7 +1106,6 @@ def test_tool_error_result_logs_at_error_log_level( expected_level: int, message_fragment: str, caplog: pytest.LogCaptureFixture, - monkeypatch: pytest.MonkeyPatch, ) -> None: """``_log_error`` honors ``log_level``: WARNING expected, ERROR not. @@ -1127,10 +1123,10 @@ def test_tool_error_result_logs_at_error_log_level( """ from fastmcp import Client - # fastmcp's logger doesn't propagate to root (rich handler); - # re-enable propagation so caplog sees the records. - monkeypatch.setattr(logging.getLogger("fastmcp"), "propagate", True) - + # fastmcp's logger is non-propagating (rich handler); pytest >=9.1.0 + # attaches caplog directly to it. ``fastmcp.errors`` records reach + # caplog by propagating up to ``fastmcp`` — re-enabling propagation + # to root would then double-capture each emit (``fastmcp`` + root). probe = _error_probe_server() async def _call() -> None: diff --git a/tests/test_utils.py b/tests/test_utils.py index 3b25f69..dee986c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -914,7 +914,6 @@ def test_map_exception_operator_faults_stay_at_error(raised: Exception) -> None: def test_expected_tool_error_logs_warning_through_server( caplog: pytest.LogCaptureFixture, - monkeypatch: pytest.MonkeyPatch, ) -> None: """Fastmcp's server-layer error log honors ``ExpectedToolError.log_level``. @@ -922,10 +921,6 @@ def test_expected_tool_error_logs_warning_through_server( assertion isolates fastmcp's own ``Error calling tool`` record — the project middleware's log behavior is covered in ``test_middleware.py``. - - fastmcp sets ``propagate = False`` on its logger (it installs a - rich handler instead), which hides records from caplog's - root-logger handler — re-enable propagation for the test. """ import asyncio import logging @@ -934,8 +929,6 @@ def test_expected_tool_error_logs_warning_through_server( from libtmux_mcp._utils import ExpectedToolError - monkeypatch.setattr(logging.getLogger("fastmcp"), "propagate", True) - probe = FastMCP(name="probe") @probe.tool diff --git a/uv.lock b/uv.lock index a3eb04f..58cb2f0 100644 --- a/uv.lock +++ b/uv.lock @@ -1261,7 +1261,7 @@ dev = [ { name = "gp-libs" }, { name = "gp-sphinx", specifier = "==0.0.1a31" }, { name = "mypy" }, - { name = "pytest" }, + { name = "pytest", specifier = ">=9.1.0" }, { name = "pytest-cov" }, { name = "pytest-mock" }, { name = "pytest-rerunfailures" }, @@ -1289,7 +1289,7 @@ lint = [ ] testing = [ { name = "gp-libs" }, - { name = "pytest" }, + { name = "pytest", specifier = ">=9.1.0" }, { name = "pytest-mock" }, { name = "pytest-rerunfailures" }, { name = "pytest-watcher" },