You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/06/04 19:03:44 UTC
(superset) branch master updated: fix(reports): stamp email subject date at send time, not import time (#40693)
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 9a31362fa5e fix(reports): stamp email subject date at send time, not import time (#40693)
9a31362fa5e is described below
commit 9a31362fa5ed16c8a1b7daf092bb5d944f4eafa8
Author: Evan Rusackas <ev...@preset.io>
AuthorDate: Thu Jun 4 12:03:28 2026 -0700
fix(reports): stamp email subject date at send time, not import time (#40693)
Co-authored-by: Claude Opus 4.8 <no...@anthropic.com>
---
superset/reports/notifications/email.py | 16 +++++++++++++---
.../unit_tests/reports/notifications/email_tests.py | 21 +++++++++++++++------
2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/superset/reports/notifications/email.py b/superset/reports/notifications/email.py
index 4c172afd791..b0485d21828 100644
--- a/superset/reports/notifications/email.py
+++ b/superset/reports/notifications/email.py
@@ -28,8 +28,8 @@ from pytz import timezone
from superset import is_feature_enabled
from superset.exceptions import SupersetErrorsException
-from superset.reports.models import ReportRecipientType
-from superset.reports.notifications.base import BaseNotification
+from superset.reports.models import ReportRecipients, ReportRecipientType
+from superset.reports.notifications.base import BaseNotification, NotificationContent
from superset.reports.notifications.exceptions import NotificationError
from superset.utils import json
from superset.utils.core import HeaderDataType, send_email_smtp
@@ -83,7 +83,17 @@ class EmailNotification(BaseNotification): # pylint: disable=too-few-public-met
"""
type = ReportRecipientType.EMAIL
- now = datetime.now(timezone("UTC"))
+
+ def __init__(
+ self, recipient: ReportRecipients, content: NotificationContent
+ ) -> None:
+ super().__init__(recipient, content)
+ # Stamp each notification with its own timestamp at construction, which
+ # happens per recipient immediately before the email is dispatched. The
+ # date rendered into the subject (when DATE_FORMAT_IN_EMAIL_SUBJECT is
+ # enabled) therefore tracks the dispatch time. A module- or class-level
+ # value would instead freeze on the first import in a long-running worker.
+ self.now = datetime.now(timezone("UTC"))
@property
def _name(self) -> str:
diff --git a/tests/unit_tests/reports/notifications/email_tests.py b/tests/unit_tests/reports/notifications/email_tests.py
index 54fb2d4b30e..b7dcc1df2d7 100644
--- a/tests/unit_tests/reports/notifications/email_tests.py
+++ b/tests/unit_tests/reports/notifications/email_tests.py
@@ -17,6 +17,7 @@
from datetime import datetime
import pandas as pd
+from freezegun import freeze_time
from pytz import timezone
from tests.unit_tests.conftest import with_feature_flags
@@ -107,8 +108,6 @@ def test_email_subject_with_datetime() -> None:
from superset.reports.notifications.base import NotificationContent
from superset.reports.notifications.email import EmailNotification
- now = datetime.now(timezone("UTC"))
-
datetime_pattern = "%Y-%m-%d"
content = NotificationContent(
@@ -130,8 +129,18 @@ def test_email_subject_with_datetime() -> None:
"execution_id": "test-execution-id",
},
)
- subject = EmailNotification(
- recipient=ReportRecipients(type=ReportRecipientType.EMAIL), content=content
- )._get_subject()
+ # Freeze the clock to a fixed, distinctive instant and construct the
+ # notification *under* the freeze. The subject date must reflect this
+ # frozen moment, which is only possible if the timestamp is stamped per
+ # instance at construction/send time. If the timestamp were a class
+ # attribute evaluated at import time (the regression this fixes), it would
+ # carry the real import-time date instead and this assertion would fail.
+ frozen_now = datetime(2021, 4, 22, 12, 0, 0, tzinfo=timezone("UTC"))
+ with freeze_time(frozen_now):
+ notification = EmailNotification(
+ recipient=ReportRecipients(type=ReportRecipientType.EMAIL),
+ content=content,
+ )
+ subject = notification._get_subject()
assert datetime_pattern not in subject
- assert now.strftime(datetime_pattern) in subject
+ assert frozen_now.strftime(datetime_pattern) in subject