modern-di-grpc 2.1.0 — adopt the modern-di integration kit
Maintenance release. No public API change — DIInterceptor,
DIAioInterceptor, FromDI, inject, fetch_di_container, and
grpc_context_provider keep their signatures and behavior. Swaps this
package's hand-rolled connection-context seeding and marker resolution for
the shared primitives in
modern_di.integrations,
shipped in
modern-di 2.28.0.
Eighth of 13 planned adapter conversions across the modern-di ecosystem
(after
modern-di-starlette 2.2.0,
modern-di-fastapi 2.10.0,
modern-di-litestar 2.13.0,
modern-di-aiohttp 2.2.0,
modern-di-flask 2.1.0,
modern-di-faststream 2.10.0,
and
modern-di-typer 2.3.0).
This conversion was explicitly anticipated by modern-di's own decision
record addendum: "grpc's _build_child collapses to one bind() call,
dropping its post-hoc set_context entirely." gRPC has exactly one
connection provider, so bind() is used directly with no
classify_connection.
Internal refactors
_build_childcollapsed from a two-step "build then post-hoc
set_context" into oneintegrations.bind(grpc_context_provider, context)call, passing the derived context directly to
build_child_container(scope=match.scope, context=match.context)._FromDIis gone;FromDI = integrations.from_di._parse_inject_params
is deleted entirely (its body duplicatedintegrations.parse_markers
exactly);injectnow callsintegrations.parse_markersdirectly.
_resolvedelegates tointegrations.resolve_markers.- Both
T/T_coTypeVars and thedataclassesimport are removed (dead
once the old marker class is gone) — this repo'sinjectwas never
generic overT, so unlike themodern-di-typer/modern-di-flask
conversions, neither TypeVar survives. architecture/dependency-injection.md's "Per-RPC scope" and "FromDI
marker +injectdecorator" sections promoted to describe the new
internals.
Packaging
- Bumps the
modern-difloor to>=2.28,<3.
Downstream
No action needed — the public API (DIInterceptor, DIAioInterceptor,
FromDI, inject, fetch_di_container, grpc_context_provider) is
unchanged. Upgrading only requires modern-di>=2.28.0.
Internals
- 100% line coverage;
ruff,tyclean across Python 3.10–3.14. Both the
sync (DIInterceptor) and async (DIAioInterceptor) paths are fully
exercised. - Built via
subagent-driven-development: 5 planned tasks, each with an
independent spec+quality review; a whole-branch review before merge that
verified at the source level (Container/ContextRegistryinternals)
that passing context at construction time is provably equivalent to the
old post-hocset_contextcall.