From 3ecf5b8ae1901be8950b31e6af8201d19d8c30e5 Mon Sep 17 00:00:00 2001 From: IlyaKhalafi Date: Mon, 19 Oct 2026 12:50:00 +0000 Subject: [PATCH] Keep shared schedule labels isolated --- taskiq/schedule_sources/label_based.py | 2 +- tests/scheduler/test_label_based_sched.py | 47 +++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/taskiq/schedule_sources/label_based.py b/taskiq/schedule_sources/label_based.py index 663e1db0..04b31c85 100644 --- a/taskiq/schedule_sources/label_based.py +++ b/taskiq/schedule_sources/label_based.py @@ -46,7 +46,7 @@ async def startup(self) -> None: for schedule in task.labels.get("schedule", []): if not {"cron", "interval", "time"} & schedule.keys(): continue - labels = schedule.get("labels", {}) + labels = schedule.get("labels", {}).copy() task_labels = {k: v for k, v in task.labels.items() if k != "schedule"} diff --git a/tests/scheduler/test_label_based_sched.py b/tests/scheduler/test_label_based_sched.py index 81f5edfe..e90e9303 100644 --- a/tests/scheduler/test_label_based_sched.py +++ b/tests/scheduler/test_label_based_sched.py @@ -117,3 +117,50 @@ def task(number: int) -> None: tasks = [task.args for task in await scheduler.sources[0].get_schedules()] assert tasks == [[2], [3]] # [1] not in a list as it was enqueued above sched_task.cancel() + + +async def test_schedule_discovery_keeps_shared_labels_isolated() -> None: + broker = InMemoryBroker() + schedule = {"cron": "* * * * *", "labels": {"origin": "nightly"}} + + @broker.task(task_name="dedicated_task", schedule=[schedule], queue="dedicated") + async def dedicated_task() -> None: + pass + + @broker.task(task_name="default_task", schedule=[schedule]) + async def default_task() -> None: + pass + + source = LabelScheduleSource(broker) + for _ in range(2): + await source.startup() + schedules = { + task.task_name: task.labels for task in await source.get_schedules() + } + assert schedules == { + "dedicated_task": {"origin": "nightly", "queue": "dedicated"}, + "default_task": {"origin": "nightly"}, + } + assert schedule["labels"] == {"origin": "nightly"} + + await broker.shutdown() + + +async def test_schedule_discovery_preserves_task_label_precedence() -> None: + broker = InMemoryBroker() + schedule = { + "cron": "* * * * *", + "labels": {"queue": "schedule", "origin": "nightly"}, + } + + @broker.task(task_name="task", schedule=[schedule], queue="task") + async def task() -> None: + pass + + source = LabelScheduleSource(broker) + await source.startup() + schedules = await source.get_schedules() + + assert schedules[0].labels == {"queue": "task", "origin": "nightly"} + assert schedule["labels"] == {"queue": "schedule", "origin": "nightly"} + await broker.shutdown()