Skip to content

fix(typing): accept every broker where BrokerUsecase[Any, Any] is annotated - #3222

Merged
IvanKirpichnikov merged 6 commits into
mainfrom
fix/broker-config-covariant
Sep 23, 2026
Merged

IvanKirpichnikov merged 6 commits into
mainfrom
fix/broker-config-covariant

Conversation

@Lancetnik

@Lancetnik Lancetnik commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Description

Since 0.7.6 an integration annotated with BrokerUsecase[Any, Any] rejects every concrete broker. dishka's setup_dishka(broker=...) is the reported case:

error: Argument "broker" to "setup_dishka" has incompatible type "RabbitBroker"; expected "BrokerUsecase[Any, Any, BrokerConfig] | None"  [arg-type]

#3029 made each broker bind the third parameter of BrokerUsecase to its own config (BrokerUsecase[IncomingMessage, RobustConnection, RabbitBrokerConfig]). That parameter was an invariant TypeVar with default=BrokerConfig, so BrokerUsecase[Any, Any] expands to BrokerUsecase[Any, Any, BrokerConfig], and no subclass config matches it. Before 0.7.6 every broker left the parameter at its default, so the types happened to line up.

What changes

  • BrokerConfigType becomes covariant and is renamed to BrokerConfigType_co, as ruff's PLC0105 requires and as the other covariant TypeVars in the repo are named. It lives in faststream._internal, so the rename is not public API.
  • tests/mypy/broker.py passes all six brokers to functions annotated with BrokerUsecase[Any, Any] and BrokerUsecase[Any, Any, Any]. tests/mypy is read by mypy, pyright and pyrefly, so the behaviour is pinned under all three.

Checked

  • Without the source change the new test fails mypy with six arg-type errors, one per broker. With it, it passes.
  • just mypy (1850 files), just pyright, just pyrefly, just linter, just import-linter and just slotscheck are clean.

Trade-off

self.config is mutable, so covariance is not strictly sound. Neither checker flags it, and it restores what every third-party wrapper relied on until 0.7.5.

Type of change

  • Bug fix (a non-breaking change that resolves an issue)

…otated

Since 0.7.6 each broker binds the third parameter of BrokerUsecase to its
own config class. The parameter was invariant with a BrokerConfig default,
so `BrokerUsecase[Any, Any]` meant `BrokerUsecase[Any, Any, BrokerConfig]`
and rejected every concrete broker: dishka's `setup_dishka(broker=...)`
failed mypy with arg-type for all of them.

Make the TypeVar covariant, rename it to BrokerConfigType_co as PLC0105
asks, and pin the behaviour in tests/mypy, which mypy, pyright and pyrefly
all read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label Sep 23, 2026
Lancetnik and others added 3 commits September 23, 2026 19:41
…s it to the PR

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Comment thread faststream/_internal/configs/broker.py Outdated
Comment thread faststream/_internal/configs/broker.py Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@IvanKirpichnikov
IvanKirpichnikov added this pull request to the merge queue Sep 23, 2026
Merged via the queue into main with commit a7f4e0a Sep 23, 2026
33 checks passed
@IvanKirpichnikov
IvanKirpichnikov deleted the fix/broker-config-covariant branch September 23, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants