Skip to content

Releases: modern-python/modern-di-celery

Release list

2.0.1

Choose a tag to compare

@github-actions github-actions released this 11 Jul 10:05
92d96bb

modern-di-celery 2.0.1 — @inject variadic fail-fast

A patch release fixing silent argument corruption in @inject.

Fix

  • @inject now rejects *args/**kwargs at decoration time. Since 2.0.0,
    @inject binds a task's arguments to its visible signature by name (which is
    what makes injection parameter-order-insensitive). That by-name call could not
    faithfully forward variadic parameters: inspect.Signature.bind stores
    *args/**kwargs values under the literal names "args"/"kwargs", so a
    task declaring *args/**kwargs alongside a FromDI parameter had its
    real payload silently misrouted into a keyword argument (e.g. a caller's
    (1, 2, foo="bar") arrived inside the task as args=(), kwargs={"args": (1, 2), "kwargs": {"foo": "bar"}}) instead of raising.

    @inject now raises a clear TypeError at decoration time when a task
    declares a VAR_POSITIONAL or VAR_KEYWORD parameter together with a FromDI
    parameter, naming the offending parameter and pointing at explicit named
    parameters as the fix. A task with no FromDI parameter is returned
    unchanged and may use *args/**kwargs freely.

Downstream

  • Potentially breaking, intentionally. A task that previously combined
    @inject/DITask with *args/**kwargs and a FromDI parameter was already
    broken at runtime (silently corrupted arguments); it now fails loudly at import
    time. Replace the variadic parameters with explicit named parameters.

Internals

  • 100% line coverage; ruff, ty, and eof-fixer clean. Two new tests cover
    the VAR_POSITIONAL and VAR_KEYWORD rejection paths.

2.0.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 11:58
fcc2eb1

modern-di-celery 2.0.0 — first release

First release of the Celery integration for modern-di. It wires a
modern-di container into a
Celery 5.x app and resolves dependencies into task
handlers, scoped per task. The version starts at 2.0.0 to track the modern-di
2.x ecosystem alongside the other official integrations.

A Celery task is a plain callable with no Depends-style seam, so this
integration follows modern-di's decorator path (like modern-di-typer),
fully synchronous — a natural fit, since Celery workers are synchronous.

Feature

  • setup_di(app, container). Stores the root container on app.conf (read
    back with fetch_di_container(app)), and wires the container's lifecycle to
    Celery's worker-process signals — reopening it on worker_process_init (each
    forked worker process gets its own open container) and closing it on
    worker_process_shutdown. Returns the container.
  • Per-task child containers. inject opens one Scope.REQUEST child
    container per task, resolves the marked dependencies, and closes it
    (close_sync) when the task finishes — including on the error path.
  • FromDI + @inject. Mark a task parameter with
    Annotated[T, FromDI(provider_or_type)] and decorate the task with @inject;
    the decorator resolves each marked parameter and rewrites the task signature
    so Celery binds only the caller's real arguments. Injection is
    parameter-order-insensitive — FromDI params may appear anywhere in the
    signature.
  • DITask base class. Set Celery(task_cls=DITask) or @app.task(base=DITask)
    to inject every task without a per-task @inject; DITask applies inject
    to the task's run and resets the task header so Celery still binds only real
    args.

Packaging

  • Requires celery>=5,<6 and modern-di>=2.25,<3; Python 3.10–3.14.
  • Ships py.typed; zero runtime dependencies beyond Celery and modern-di.
  • Resolution and finalizers are synchronous; there is no connection object (a
    Celery task carries no framework request object).

Downstream

No action needed — this is a new package.

Internals

  • 100% line coverage; ruff, ty, and eof-fixer clean across Python
    3.10–3.14. Tests use Celery's eager execution (task_always_eager).
  • Uses the portable planning convention (planning/) with an architecture/
    truth home; releases are tag-driven.