From 6a2b973427466a71737f248f9eb988d4910ec822 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Wed, 27 May 2026 12:13:11 +0200 Subject: [PATCH 1/2] Ref #51 -- Resolve sentry_monitor_config type ambigutity --- README.md | 4 ++-- crontask/__init__.py | 11 +++++++---- crontask/contrib/sentry.py | 2 +- tests/test_tasks.py | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f728e9f..6dae63d 100644 --- a/README.md +++ b/README.md @@ -110,11 +110,11 @@ The monitor's slug will be the actor's name. Like `my_task` in the example above Certain triggers are not supported by Sentry as well as sub-minute intervals. In these cases, no monitor will be created and no telemetry will be sent. -Pass a custom config via `sentry_monitor_config` or set it to `False` +Pass a custom config via `sentry_monitor_config` or set it to a falsy value to disable Sentry monitoring for a single task: ```python -@cron("* * * * *", sentry_monitor_config=False) +@cron("* * * * *", sentry_monitor_config={}) @task def my_task_without_sentry(): ... ``` diff --git a/crontask/__init__.py b/crontask/__init__.py index d3eab36..6075bd9 100644 --- a/crontask/__init__.py +++ b/crontask/__init__.py @@ -34,12 +34,13 @@ def add_job(self, *args, **kwargs): scheduler = LazyBlockingScheduler() +UNSET = object() def cron( schedule: str | BaseTrigger, *, - sentry_monitor_config: dict[str, typing.Any] | bool | None = None, + sentry_monitor_config: dict[str, dict[str, str | int] | str] = UNSET, ) -> typing.Callable[[Task], Task]: """ Run task on a scheduler with a cron schedule. @@ -52,7 +53,7 @@ def cron_test(): Args: schedule: A cron schedule string or an APScheduler trigger. - sentry_monitor_config: A Sentry monitor configuration dict or False to disable monitoring. + sentry_monitor_config: A Sentry monitor configuration dict or None to disable monitoring. """ @@ -73,11 +74,13 @@ def decorator(task: Task) -> Task: else: trigger = schedule - if sentry_monitor_config is not False: + if sentry_monitor_config: task = sentry.monitor_cron_task( task, trigger, - sentry_monitor_config=sentry_monitor_config, + sentry_monitor_config={} + if sentry_monitor_config is UNSET + else sentry_monitor_config, ) scheduler.add_job( diff --git a/crontask/contrib/sentry.py b/crontask/contrib/sentry.py index a1da310..a8dc326 100644 --- a/crontask/contrib/sentry.py +++ b/crontask/contrib/sentry.py @@ -65,7 +65,7 @@ def trigger_to_monitor_config( def monitor_cron_task( task: Task, trigger: BaseTrigger, - sentry_monitor_config: dict[str, dict[str, str | int] | str] | None = None, + sentry_monitor_config: dict[str, dict[str, str | int] | str], ) -> Task: """ Wrap the task function in a Sentry monitor for a suitable trigger. diff --git a/tests/test_tasks.py b/tests/test_tasks.py index b4bd775..2ab9534 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -166,4 +166,4 @@ def test_cron__sentry_monitor_config_none(monkeypatch): mock_monitor.assert_called_once() call_args = mock_monitor.call_args - assert call_args.kwargs["sentry_monitor_config"] is None + assert not call_args.kwargs["sentry_monitor_config"] From 8a17a65d7dc7f5f4760e1a37df5fc3a40053c8bf Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Wed, 27 May 2026 12:41:12 +0200 Subject: [PATCH 2/2] address review comments --- README.md | 4 ++-- crontask/__init__.py | 4 ++-- tests/test_tasks.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6dae63d..369120e 100644 --- a/README.md +++ b/README.md @@ -110,11 +110,11 @@ The monitor's slug will be the actor's name. Like `my_task` in the example above Certain triggers are not supported by Sentry as well as sub-minute intervals. In these cases, no monitor will be created and no telemetry will be sent. -Pass a custom config via `sentry_monitor_config` or set it to a falsy value +Pass a custom config via `sentry_monitor_config` or set it to `None` to disable Sentry monitoring for a single task: ```python -@cron("* * * * *", sentry_monitor_config={}) +@cron("* * * * *", sentry_monitor_config=None) @task def my_task_without_sentry(): ... ``` diff --git a/crontask/__init__.py b/crontask/__init__.py index 6075bd9..7052443 100644 --- a/crontask/__init__.py +++ b/crontask/__init__.py @@ -40,7 +40,7 @@ def add_job(self, *args, **kwargs): def cron( schedule: str | BaseTrigger, *, - sentry_monitor_config: dict[str, dict[str, str | int] | str] = UNSET, + sentry_monitor_config: dict[str, dict[str, str | int] | str] | None = UNSET, ) -> typing.Callable[[Task], Task]: """ Run task on a scheduler with a cron schedule. @@ -74,7 +74,7 @@ def decorator(task: Task) -> Task: else: trigger = schedule - if sentry_monitor_config: + if sentry_monitor_config is not None: task = sentry.monitor_cron_task( task, trigger, diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 2ab9534..398a62c 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -128,7 +128,7 @@ def test_cron__sentry_monitor_config_false(monkeypatch): mock_monitor = Mock(return_value=tasks.heartbeat) monkeypatch.setattr("crontask.sentry.monitor_cron_task", mock_monitor) - cron("* * * * *", sentry_monitor_config=False)(tasks.heartbeat) + cron("* * * * *", sentry_monitor_config=None)(tasks.heartbeat) mock_monitor.assert_not_called() assert len(scheduler.get_jobs()) == 1 @@ -166,4 +166,4 @@ def test_cron__sentry_monitor_config_none(monkeypatch): mock_monitor.assert_called_once() call_args = mock_monitor.call_args - assert not call_args.kwargs["sentry_monitor_config"] + assert call_args.kwargs["sentry_monitor_config"] == {}