diff --git a/planning/releases/2.1.0.md b/planning/releases/2.1.0.md new file mode 100644 index 0000000..e94a57a --- /dev/null +++ b/planning/releases/2.1.0.md @@ -0,0 +1,67 @@ +# modern-di-taskiq 2.1.0 — adopt the modern-di integration kit + +Maintenance release. **No public API change** — `FromDI`, `setup_di`, +`fetch_di_container`, and `taskiq_message_provider` keep their signatures +and behavior. Swaps this package's hand-rolled connection-context derivation +and marker resolution for the shared primitives in +[`modern_di.integrations`](https://github.com/modern-python/modern-di/blob/main/architecture/integration-kit.md), +shipped in +[modern-di 2.28.0](https://github.com/modern-python/modern-di/releases/tag/2.28.0). +Eleventh of 13 planned adapter conversions across the `modern-di` ecosystem +(after +[`modern-di-starlette` 2.2.0](https://github.com/modern-python/modern-di-starlette/releases/tag/2.2.0), +[`modern-di-fastapi` 2.10.0](https://github.com/modern-python/modern-di-fastapi/releases/tag/2.10.0), +[`modern-di-litestar` 2.13.0](https://github.com/modern-python/modern-di-litestar/releases/tag/2.13.0), +[`modern-di-aiohttp` 2.2.0](https://github.com/modern-python/modern-di-aiohttp/releases/tag/2.2.0), +[`modern-di-flask` 2.1.0](https://github.com/modern-python/modern-di-flask/releases/tag/2.1.0), +[`modern-di-faststream` 2.10.0](https://github.com/modern-python/modern-di-faststream/releases/tag/2.10.0), +[`modern-di-typer` 2.3.0](https://github.com/modern-python/modern-di-typer/releases/tag/2.3.0), +[`modern-di-grpc` 2.1.0](https://github.com/modern-python/modern-di-grpc/releases/tag/2.1.0), +[`modern-di-celery` 2.1.0](https://github.com/modern-python/modern-di-celery/releases/tag/2.1.0), +and +[`modern-di-arq` 2.1.0](https://github.com/modern-python/modern-di-arq/releases/tag/2.1.0)). +taskiq is a **native-DI adapter** (uses taskiq's own `TaskiqDepends`) with a +single connection provider, so — like grpc — it uses `bind()` directly with +no `classify_connection`. + +## Internal refactors + +- **`build_di_container` now derives scope/context via + `integrations.bind(taskiq_message_provider, context.message)`**, and opens + the per-task child via `async with ... as container: yield container` — + replacing the manual `try`/`finally: await container.close_async()`. taskiq + has a single connection provider, so there's no `classify_connection` + dispatch (nothing to dispatch across). +- **`Dependency`'s field is renamed from a raw `dependency` to + `marker: integrations.Marker[T_co]`; `__call__` delegates to + `self.marker.resolve(request_container)`.** `FromDI` now constructs + `Dependency(integrations.Marker(dependency))` — its own signature + (`dependency, *, use_cache`) is unchanged, and it still wraps taskiq's own + `TaskiqDepends`. +- Like `modern-di-fastapi`/`modern-di-litestar`/`modern-di-faststream`, this + package is a **native-DI** adapter: no hand-rolled `@inject` decorator, no + `parse_markers`/`resolve_markers` usage, and no imports become dead. +- `setup_di`, `fetch_di_container`, and the + `WORKER_STARTUP`/`WORKER_SHUTDOWN` root-lifecycle wiring are untouched. +- `architecture/dependency-injection.md`'s "Per-task scope" and "Resolution" + sections promoted to describe the new internals. + +## Packaging + +- Bumps the `modern-di` floor to `>=2.28,<3`. + +## Downstream + +No action needed — the public API (`FromDI`, `setup_di`, +`fetch_di_container`, `taskiq_message_provider`) is unchanged. Upgrading +only requires `modern-di>=2.28.0`. + +## Internals + +- 100% line coverage; `ruff`, `ty` clean across Python 3.10–3.14. Tests use + `taskiq.InMemoryBroker` (no external broker). +- Built via `subagent-driven-development`: 5 planned tasks, each with an + independent spec+quality review; a whole-branch review before merge that + traced the async-generator-inside-`async with` structure's close-timing + against the original `try`/`finally` on both the normal and task-error + paths.