Skip to content

pytest filterwarnings suppresses the DeprecationWarnings this project needs to see #111

Description

@tony

Summary

pyproject.toml silences DeprecationWarning for libtmux.*, libtmux_mcp.*, and tests. Because library deprecations are raised with stacklevel pointing at the caller, those three module patterns are exactly where a deprecation this project needs to act on gets attributed — so the filters suppress the signal rather than third-party noise. They are already hiding a real one.

The filters

pyproject.toml#L258-L263:

filterwarnings = [
  "ignore:The frontend.Option(Parser)? class.*:DeprecationWarning::",
  "ignore::DeprecationWarning:libtmux.*:",
  "ignore::DeprecationWarning:libtmux_mcp.*:",
  "ignore::DeprecationWarning:tests:",
]

The first entry is a narrow, message-scoped filter for a docutils warning and is fine. The other three are blanket category filters scoped by module.

Why this suppresses the wrong thing

A warning's module is matched against the __name__ of the frame the warning is attributed to, which stacklevel controls. Libraries raise deprecations with stacklevel=2 so the warning points at the line that used the deprecated API — which for this project is a module under libtmux_mcp.* or a test body under tests. The filters therefore hit precisely the warnings that indicate this codebase needs to change, while a warning raised from an unrelated package still surfaces.

Compounding it, FastMCPDeprecationWarning subclasses DeprecationWarning, so the category filters catch FastMCP's own deprecations too:

FastMCPDeprecationWarning.__mro__ -> (FastMCPDeprecationWarning, DeprecationWarning, Warning, ...)
issubclass(FastMCPDeprecationWarning, DeprecationWarning) -> True

Verified by A/B probe under the repo's real config — two tests in one run, one warning emitted from each namespace:

Warning attributed to Result
libtmux_mcp.server suppressed, absent from the warnings summary
some_other_package.thing surfaces normally

It is already hiding something

Removing the three blanket entries and running the suite: 801 passed, 2 warnings, both real and both previously invisible.

tests/test_wait_for_tools.py#L57-L58:

DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for
removal in Python 3.16; use inspect.iscoroutinefunction() instead

Nothing else warns. The suppression is buying no quiet — it is costing exactly one signal, and that signal is a scheduled removal from the standard library.

Why it matters now

SEP-2596 obliges Tier 1 SDKs to "emit a runtime warning when a deprecated feature is exercised, using the language's idiomatic mechanism (for example Python's DeprecationWarning)" once a feature enters the Deprecated state. That machinery is about to start firing, against a suite configured not to listen:

  • Spec revision 2026-07-28 deprecates Roots, Sampling, and Logging (SEP-2577).
  • mcp 2.0.0 is targeted for the same date; it removes the mcp.types submodule in favour of a standalone package and drops camelCase attribute access on protocol models.
  • fastmcp v4 is in alpha against the <4.0.0 ceiling this project pins.

There is real exposure behind those: 13 .inputSchema reads across tests/test_history.py and tests/test_spawn_tools_history.py, mcp.types imports in src/libtmux_mcp/middleware.py, and _client_label() reading client identity off the initialize handshake that 2026-07-28 removes. None of it breaks today — fastmcp 3.4.4 pins mcp<2.0, so 2.x cannot resolve into this environment — but the warnings are how that transition is supposed to announce itself.

Proposed change

  • Delete the three blanket ignore::DeprecationWarning:<module>: entries. Keep the message-scoped docutils filter.
  • Replace asyncio.iscoroutinefunction with inspect.iscoroutinefunction at the two call sites.

Deliberately not proposing error::DeprecationWarning. This project pins two fast-moving pre-2.0 dependencies, and escalating to an error means an upstream patch release can turn CI red with no local change. Visible-but-not-fatal restores the signal without handing release timing control of the build to upstream. Worth revisiting once mcp 2.x and fastmcp v4 have settled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions