Skip to content

mcp(test[middleware]): Fix caplog double-capture on pytest 9.1.0#83

Merged
tony merged 4 commits into
mainfrom
fix-caplog-double-capture-pytest-910
Jun 21, 2026
Merged

mcp(test[middleware]): Fix caplog double-capture on pytest 9.1.0#83
tony merged 4 commits into
mainfrom
fix-caplog-double-capture-pytest-910

Conversation

@tony

@tony tony commented Jun 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Fix test_tool_error_result_logs_at_error_log_level, which fails on pytest 9.1.0 because caplog records each error-log emit twice (assert [30, 30] == [30]). This reds main and any branch carrying the dev-dependency bump.
  • Remove the obsolete propagate=True workaround suite-wide — the failing test plus two sister tests (test_send_keys_batch_schema_validation_redacts_inputs, test_expected_tool_error_logs_warning_through_server) all forced fastmcp logger propagation so caplog could see records. pytest 9.1.0 captures non-propagating loggers natively, making the workaround dead weight that double-captures each emit.
  • Floor pytest>=9.1.0 in the dev and testing groups so the suite's reliance on that capture behavior is a declared contract, not an implicit one.

Root cause

fastmcp keeps its fastmcp logger non-propagating (it owns a Rich handler). The tests compensated by forcing fastmcp.propagate = True so caplog — which historically only listened at the root logger — could see the records.

pytest 9.1.0 shipped #3697 "Logging capture now works for non-propagating loggers": catching_logs.__enter__ now attaches its LogCaptureHandler directly to every non-propagating logger at setup, including fastmcp. A record emitted on fastmcp.errors reaches caplog by propagating up to fastmcp (where the handler now lives); re-enabling propagation to root captures the same emit a second time.

The error is logged once — only the capture was doubled:

Test setup Records caplog sees
With propagate=True workaround (before) 2
Without the workaround (after) 1

test_tool_error_result_logs_at_error_log_level asserts an exact record count, so it failed outright. The two sister tests assert on log content, so the duplication was silent — but the workaround was equally obsolete there.

Changes by area

  • tests/test_middleware.py: Drop the propagate=True workaround (and now-unused monkeypatch arg) from test_tool_error_result_logs_at_error_log_level and test_send_keys_batch_schema_validation_redacts_inputs; caplog captures fastmcp's logger natively.
  • tests/test_utils.py: Drop the same workaround from test_expected_tool_error_logs_warning_through_server, including the docstring paragraph that described it.
  • pyproject.toml / uv.lock: Floor pytest>=9.1.0 in dev and testing; relock.
  • CHANGES: Add a ### Development entry.

Verification

The workaround is fully removed from the test suite (the monkeypatch.setattr(..., "propagate", ...) target):

rg -n '"propagate"' tests/

The floor is declared in both dependency groups:

rg -n 'pytest>=9\.1\.0' pyproject.toml

Test plan

  • test_tool_error_result_logs_at_error_log_level (all parametrizations) passes with --reruns 0
  • test_send_keys_batch_schema_validation_redacts_inputs and test_expected_tool_error_logs_warning_through_server pass without the workaround
  • uv run ruff check . and uv run ruff format --check .
  • uv run mypy
  • Full suite green with uv run pytest --reruns 0
  • just build-docs

@codecov-commenter

codecov-commenter commented Jun 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.73%. Comparing base (188784b) to head (8d43f6c).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #83      +/-   ##
==========================================
+ Coverage   84.67%   84.73%   +0.06%     
==========================================
  Files          43       43              
  Lines        3197     3197              
  Branches      438      438              
==========================================
+ Hits         2707     2709       +2     
+ Misses        360      359       -1     
+ Partials      130      129       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tony tony force-pushed the fix-caplog-double-capture-pytest-910 branch 3 times, most recently from a1557b3 to 62a72d8 Compare June 21, 2026 15:10
@tony

tony commented Jun 21, 2026

Copy link
Copy Markdown
Member Author

Code review

No issues found. Checked for bugs and AGENTS.md compliance.

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

tony added 4 commits June 21, 2026 10:49
why: pytest 9.1.0 captures non-propagating loggers directly. The
test forced fastmcp logger propagation so caplog could see its
records; under 9.1.0 that double-captures each emit, so the
assertion saw two records instead of one.

what:
- Drop the propagate=True monkeypatch and the now-unused
  monkeypatch fixture arg; caplog sees fastmcp natively
why: The middleware error-logging test relies on pytest 9.1.0's
direct capture of non-propagating loggers; make the requirement
explicit instead of leaving it implied by the lockfile.

what:
- Raise pytest floor to >=9.1.0 in dev and testing groups
- Relock
why: Record the dev-only fix in the unreleased changelog.

what:
- Add a Development entry linking the PR
why: pytest 9.1.0 captures non-propagating loggers natively, so
forcing the fastmcp logger to propagate is dead weight and
double-captures each emit. These two tests pre-date the floor and
kept the workaround; their content/existential assertions masked
the duplication.

what:
- test_send_keys_batch_schema_validation_redacts_inputs: drop the
  propagate loop and the now-unused monkeypatch arg
- test_expected_tool_error_logs_warning_through_server: drop the
  monkeypatch call and its stale docstring rationale
@tony tony force-pushed the fix-caplog-double-capture-pytest-910 branch from 62a72d8 to 8d43f6c Compare June 21, 2026 15:53
@tony tony merged commit b8e340e into main Jun 21, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants