Opened 3 weeks ago

Last modified 3 weeks ago

#36816 assigned New feature

Allow **kwargs in @task decorator to support custom Task subclasses

Reported by: Pietro Owned by: Nilesh Pahari
Component: Tasks Version: dev
Severity: Normal Keywords: task
Cc: Nilesh Pahari, Jake Howard Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Currently, the @task decorator accepts a fixed set of parameters and passes only those to task_class:

Problem: When using a custom backend with a custom task_class that accepts additional parameters (e.g., max_retries, timeout), there's no way to pass those through the decorator.

def task(
    function=None,
    *,
    priority=DEFAULT_TASK_PRIORITY,
    queue_name=DEFAULT_TASK_QUEUE_NAME,
    backend=DEFAULT_TASK_BACKEND_ALIAS,
    takes_context=False,
):
    # ...
    return task_backends[backend].task_class(
        priority=priority,
        func=f,
        queue_name=queue_name,
        backend=backend,
        takes_context=takes_context,
        run_after=None
    )

Proposed solution: Add kwargs to the decorator signature and pass it through to task_class:

def task(
    function=None,
    *,
    priority=DEFAULT_TASK_PRIORITY,
    queue_name=DEFAULT_TASK_QUEUE_NAME,
    backend=DEFAULT_TASK_BACKEND_ALIAS,
    takes_context=False,
    **kwargs,
):
    def wrapper(f):
        return task_backends[backend].task_class(
            priority=priority,
            func=f,
            queue_name=queue_name,
            backend=backend,
            takes_context=takes_context,
            run_after=None,
            **kwargs,
        )
    

Use case example:

class MyTask(Task):
    def __init__(self, *, max_retries=3, timeout=300, **kwargs):
        super().__init__(**kwargs)
        self.max_retries = max_retries
        self.timeout = timeout

# With the proposed change:
@task(backend="my_backend", max_retries=5, timeout=600)
def my_task():
    pass

This change is backwards compatible and aligns with Django's common extensibility patterns.

Change History (9)

comment:2 by Kshitij, 3 weeks ago

Type: BugNew feature

comment:3 by JaeHyuckSa, 3 weeks ago

Has patch: unset

comment:4 by Nilesh Pahari, 3 weeks ago

Cc: Nilesh Pahari added

comment:5 by Jacob Walls, 3 weeks ago

Cc: Jake Howard added

comment:6 by Jake Howard, 3 weeks ago

Triage Stage: UnreviewedAccepted

This sounds like a reasonable change to me.

As for the solution, my suggestion would be to drop all explicit arguments, and only accept **kwargs in the @task decorator - instead moving the defaults to the Task class itself. That also means that, for whatever reason, a custom Task can override defaults.

comment:7 by Nilesh Pahari, 3 weeks ago

Owner: set to Nilesh Pahari
Status: newassigned

comment:8 by Jacob Walls, 3 weeks ago

Version: 6.0dev

comment:9 by Nilesh Pahari, 3 weeks ago

Has patch: set
Note: See TracTickets for help on using tickets.
Back to Top