Confirm support for Django 4.1

Replaces deprecated `django.utils.timezone.utc` with
`datetime.timezone.utc` (available since Python 3.2).
This commit is contained in:
Tim Schilling
2022-08-24 15:24:27 -05:00
committed by GitHub
parent 6b3775a8e9
commit a4f50c4340
25 changed files with 80 additions and 89 deletions

View File

@@ -36,6 +36,8 @@ Features
* Support customizing the requests.Session for requests-based backends,
and document how this can be used to mount an adapter that simplifies
automatic retry logic. (Thanks to `@dgilmanAIDENTIFIED`_.)
* Confirm support for Django 4.1 and resolve deprecation warning regarding
``django.utils.timezone.utc``.
Fixes
~~~~~

View File

@@ -1,9 +1,9 @@
import json
from datetime import date, datetime
from datetime import date, datetime, timezone
from django.conf import settings
from django.core.mail.backends.base import BaseEmailBackend
from django.utils.timezone import is_naive, get_current_timezone, make_aware, utc
from django.utils.timezone import is_naive, get_current_timezone, make_aware
from requests.structures import CaseInsensitiveDict
from ..exceptions import (
@@ -394,7 +394,7 @@ class BasePayload:
dt = datetime(value.year, value.month, value.day) # naive, midnight
else:
try:
dt = datetime.utcfromtimestamp(value).replace(tzinfo=utc)
dt = datetime.utcfromtimestamp(value).replace(tzinfo=timezone.utc)
except (TypeError, ValueError):
return value
if is_naive(dt):

View File

@@ -1,10 +1,9 @@
import json
from datetime import datetime
from datetime import datetime, timezone
import hashlib
import hmac
from django.utils.crypto import constant_time_compare
from django.utils.timezone import utc
from .base import AnymailBaseWebhookView
from ..exceptions import AnymailConfigurationError, AnymailWebhookValidationFailure, AnymailInvalidAddress
@@ -115,7 +114,7 @@ class MailgunTrackingWebhookView(MailgunBaseWebhookView):
recipient = event_data.get('recipient')
try:
timestamp = datetime.fromtimestamp(float(event_data['timestamp']), tz=utc)
timestamp = datetime.fromtimestamp(float(event_data['timestamp']), tz=timezone.utc)
except KeyError:
timestamp = None
@@ -213,7 +212,8 @@ class MailgunTrackingWebhookView(MailgunBaseWebhookView):
"to Anymail's Mailgun *tracking* webhook URL.")
event_type = self.legacy_event_types.get(esp_event.getfirst('event'), EventType.UNKNOWN)
timestamp = datetime.fromtimestamp(int(esp_event['timestamp']), tz=utc) # use *last* value of timestamp
timestamp = datetime.fromtimestamp(
int(esp_event['timestamp']), tz=timezone.utc) # use *last* value of timestamp
# Message-Id is not documented for every event, but seems to always be included.
# (It's sometimes spelled as 'message-id', lowercase, and missing the <angle-brackets>.)
message_id = esp_event.getfirst('Message-Id', None) or esp_event.getfirst('message-id', None)
@@ -381,7 +381,7 @@ class MailgunInboundWebhookView(MailgunBaseWebhookView):
return AnymailInboundEvent(
event_type=EventType.INBOUND,
timestamp=datetime.fromtimestamp(int(request.POST['timestamp']), tz=utc),
timestamp=datetime.fromtimestamp(int(request.POST['timestamp']), tz=timezone.utc),
event_id=request.POST.get('token', None),
esp_event=esp_event,
message=message,

View File

@@ -1,7 +1,6 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from django.utils.timezone import utc
from .base import AnymailBaseWebhookView
from ..inbound import AnymailInboundMessage
@@ -68,7 +67,7 @@ class MailjetTrackingWebhookView(AnymailBaseWebhookView):
event_type = EventType.DEFERRED
try:
timestamp = datetime.fromtimestamp(esp_event['time'], tz=utc)
timestamp = datetime.fromtimestamp(esp_event['time'], tz=timezone.utc)
except (KeyError, ValueError):
timestamp = None

View File

@@ -1,11 +1,10 @@
import json
from datetime import datetime
from datetime import datetime, timezone
import hashlib
import hmac
from base64 import b64encode
from django.utils.crypto import constant_time_compare
from django.utils.timezone import utc
from .base import AnymailBaseWebhookView, AnymailCoreWebhookView
from ..exceptions import AnymailWebhookValidationFailure
@@ -109,7 +108,7 @@ class MandrillCombinedWebhookView(MandrillSignatureMixin, AnymailBaseWebhookView
event_type = self.event_types.get(esp_type, EventType.UNKNOWN)
try:
timestamp = datetime.fromtimestamp(esp_event['ts'], tz=utc)
timestamp = datetime.fromtimestamp(esp_event['ts'], tz=timezone.utc)
except (KeyError, ValueError):
timestamp = None
@@ -170,7 +169,7 @@ class MandrillCombinedWebhookView(MandrillSignatureMixin, AnymailBaseWebhookView
message.spam_score = esp_event['msg'].get('spam_report', {}).get('score', None)
try:
timestamp = datetime.fromtimestamp(esp_event['ts'], tz=utc)
timestamp = datetime.fromtimestamp(esp_event['ts'], tz=timezone.utc)
except (KeyError, ValueError):
timestamp = None

View File

@@ -1,11 +1,9 @@
import binascii
import json
from base64 import b64decode
from datetime import datetime
from datetime import datetime, timezone
from django.utils.timezone import utc
from .base import AnymailBaseWebhookView
from ..exceptions import (
AnymailInvalidAddress,
@@ -94,7 +92,7 @@ class PostalTrackingWebhookView(PostalBaseWebhookView):
raw_timestamp = esp_event.get("timestamp")
timestamp = (
datetime.fromtimestamp(int(raw_timestamp), tz=utc)
datetime.fromtimestamp(int(raw_timestamp), tz=timezone.utc)
if raw_timestamp
else None
)

View File

@@ -1,9 +1,8 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from email.parser import BytesParser
from email.policy import default as default_policy
from django.utils.timezone import utc
from .base import AnymailBaseWebhookView
from ..inbound import AnymailInboundMessage
@@ -47,7 +46,7 @@ class SendGridTrackingWebhookView(AnymailBaseWebhookView):
def esp_to_anymail_event(self, esp_event):
event_type = self.event_types.get(esp_event['event'], EventType.UNKNOWN)
try:
timestamp = datetime.fromtimestamp(esp_event['timestamp'], tz=utc)
timestamp = datetime.fromtimestamp(esp_event['timestamp'], tz=timezone.utc)
except (KeyError, ValueError):
timestamp = None

View File

@@ -1,7 +1,5 @@
import json
from datetime import datetime
from django.utils.timezone import utc
from datetime import datetime, timezone
from .base import AnymailBaseWebhookView
from ..signals import AnymailTrackingEvent, EventType, RejectReason, tracking
@@ -45,7 +43,7 @@ class SendinBlueTrackingWebhookView(AnymailBaseWebhookView):
# SendinBlue supplies "ts", "ts_event" and "date" fields, which seem to be based on the
# timezone set in the account preferences (and possibly with inconsistent DST adjustment).
# "ts_epoch" is the only field that seems to be consistently UTC; it's in milliseconds
timestamp = datetime.fromtimestamp(esp_event["ts_epoch"] / 1000.0, tz=utc)
timestamp = datetime.fromtimestamp(esp_event["ts_epoch"] / 1000.0, tz=timezone.utc)
except (KeyError, ValueError):
timestamp = None

View File

@@ -1,8 +1,6 @@
import json
from base64 import b64decode
from datetime import datetime
from django.utils.timezone import utc
from datetime import datetime, timezone
from .base import AnymailBaseWebhookView
from ..exceptions import AnymailConfigurationError
@@ -128,7 +126,7 @@ class SparkPostTrackingWebhookView(SparkPostBaseWebhookView):
event_type = self.event_types.get(event['type'], EventType.UNKNOWN)
try:
timestamp = datetime.fromtimestamp(int(event['timestamp']), tz=utc)
timestamp = datetime.fromtimestamp(int(event['timestamp']), tz=timezone.utc)
except (KeyError, TypeError, ValueError):
timestamp = None

View File

@@ -214,10 +214,9 @@ an :ref:`unsupported feature <unsupported-features>` error.
.. code-block:: python
from datetime import datetime, timedelta
from django.utils.timezone import utc
from datetime import datetime, timedelta, timezone
message.send_at = datetime.now(utc) + timedelta(hours=1)
message.send_at = datetime.now(timezone.utc) + timedelta(hours=1)
To avoid confusion, it's best to provide either an *aware*
`~datetime.datetime` (one that has its tzinfo set), or an

View File

@@ -102,6 +102,7 @@ setup(
"Framework :: Django :: 3.1",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.0",
"Framework :: Django :: 4.1",
"Environment :: Web Environment",
],
long_description=long_description,

View File

@@ -1,11 +1,10 @@
import json
from base64 import b64encode
from datetime import datetime
from datetime import datetime, timezone
from textwrap import dedent
from unittest.mock import ANY, patch
from django.test import tag
from django.utils.timezone import utc
from anymail.exceptions import AnymailAPIError, AnymailConfigurationError
from anymail.inbound import AnymailInboundMessage
@@ -131,7 +130,7 @@ class AmazonSESInboundTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
event = kwargs['event']
self.assertIsInstance(event, AnymailInboundEvent)
self.assertEqual(event.event_type, 'inbound')
self.assertEqual(event.timestamp, datetime(2018, 3, 30, 17, 21, 51, microsecond=636000, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2018, 3, 30, 17, 21, 51, microsecond=636000, tzinfo=timezone.utc))
self.assertEqual(event.event_id, "jili9m351il3gkburn7o2f0u6788stij94c8ld01")
self.assertIsInstance(event.message, AnymailInboundMessage)
self.assertEqual(event.esp_event, raw_ses_event)
@@ -185,7 +184,7 @@ class AmazonSESInboundTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
event = kwargs['event']
self.assertIsInstance(event, AnymailInboundEvent)
self.assertEqual(event.event_type, 'inbound')
self.assertEqual(event.timestamp, datetime(2018, 3, 30, 17, 21, 51, microsecond=636000, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2018, 3, 30, 17, 21, 51, microsecond=636000, tzinfo=timezone.utc))
self.assertEqual(event.event_id, "jili9m351il3gkburn7o2f0u6788stij94c8ld01")
self.assertIsInstance(event.message, AnymailInboundMessage)
self.assertEqual(event.esp_event, raw_ses_event)
@@ -248,7 +247,7 @@ class AmazonSESInboundTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
event = kwargs['event']
self.assertIsInstance(event, AnymailInboundEvent)
self.assertEqual(event.event_type, 'inbound')
self.assertEqual(event.timestamp, datetime(2018, 3, 30, 17, 21, 51, microsecond=636000, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2018, 3, 30, 17, 21, 51, microsecond=636000, tzinfo=timezone.utc))
self.assertEqual(event.event_id, "fqef5sop459utgdf4o9lqbsv7jeo73pejig34301")
self.assertIsInstance(event.message, AnymailInboundMessage)
self.assertEqual(event.esp_event, raw_ses_event)

View File

@@ -1,10 +1,9 @@
import json
import warnings
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY, patch
from django.test import SimpleTestCase, override_settings, tag
from django.utils.timezone import utc
from anymail.exceptions import AnymailConfigurationError, AnymailInsecureWebhookWarning
from anymail.signals import AnymailTrackingEvent
@@ -116,7 +115,10 @@ class AmazonSESNotificationsTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "bounced")
self.assertEqual(event.esp_event, raw_ses_event)
self.assertEqual(event.timestamp, datetime(2018, 3, 26, 17, 58, 59, microsecond=675000, tzinfo=utc)) # SNS
self.assertEqual(
event.timestamp,
datetime(2018, 3, 26, 17, 58, 59, microsecond=675000, tzinfo=timezone.utc)
) # SNS
self.assertEqual(event.message_id, "00000138111222aa-33322211-cccc-cccc-cccc-ddddaaaa0680-000000")
self.assertEqual(event.event_id, "19ba9823-d7f2-53c1-860e-cb10e0d13dfc")
self.assertEqual(event.recipient, "jane@example.com")
@@ -264,7 +266,10 @@ class AmazonSESNotificationsTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "sent")
self.assertEqual(event.esp_event, raw_ses_event)
self.assertEqual(event.timestamp, datetime(2018, 3, 26, 17, 58, 59, microsecond=675000, tzinfo=utc)) # SNS
self.assertEqual(
event.timestamp,
datetime(2018, 3, 26, 17, 58, 59, microsecond=675000, tzinfo=timezone.utc)
) # SNS
self.assertEqual(event.message_id, "7c191be45-e9aedb9a-02f9-4d12-a87d-dd0099a07f8a-000000")
self.assertEqual(event.event_id, "19ba9823-d7f2-53c1-860e-cb10e0d13dfc")
self.assertEqual(event.recipient, "recipient@example.com")

View File

@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from email.mime.text import MIMEText
from django.core import mail
@@ -7,7 +7,6 @@ from django.core.mail import get_connection, send_mail
from django.test import SimpleTestCase
from django.test.utils import override_settings
from django.utils.functional import Promise
from django.utils.timezone import utc
from django.utils.translation import gettext_lazy
from anymail.backends.test import EmailBackend as TestBackend, TestPayload
@@ -134,7 +133,7 @@ class SendDefaultsTests(TestBackendTestCase):
'SEND_DEFAULTS': {
# This isn't an exhaustive list of Anymail message attrs; just one of each type
'metadata': {'global': 'globalvalue'},
'send_at': datetime(2016, 5, 12, 4, 17, 0, tzinfo=utc),
'send_at': datetime(2016, 5, 12, 4, 17, 0, tzinfo=timezone.utc),
'tags': ['globaltag'],
'template_id': 'my-template',
'track_clicks': True,
@@ -147,7 +146,7 @@ class SendDefaultsTests(TestBackendTestCase):
params = self.get_send_params()
# All these values came from ANYMAIL_SEND_DEFAULTS:
self.assertEqual(params['metadata'], {'global': 'globalvalue'})
self.assertEqual(params['send_at'], datetime(2016, 5, 12, 4, 17, 0, tzinfo=utc))
self.assertEqual(params['send_at'], datetime(2016, 5, 12, 4, 17, 0, tzinfo=timezone.utc))
self.assertEqual(params['tags'], ['globaltag'])
self.assertEqual(params['template_id'], 'my-template')
self.assertEqual(params['track_clicks'], True)

View File

@@ -1,11 +1,10 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from io import BytesIO
from textwrap import dedent
from unittest.mock import ANY
from django.test import override_settings, tag
from django.utils.timezone import utc
from anymail.exceptions import AnymailConfigurationError
from anymail.inbound import AnymailInboundMessage
@@ -62,7 +61,7 @@ class MailgunInboundTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailInboundEvent)
self.assertEqual(event.event_type, 'inbound')
self.assertEqual(event.timestamp, datetime(2016, 4, 21, 17, 55, 30, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2016, 4, 21, 17, 55, 30, tzinfo=timezone.utc))
self.assertEqual(event.event_id, "06c96bafc3f42a66b9edd546347a2fe18dc23461fe80dc52f0")
self.assertIsInstance(event.message, AnymailInboundMessage)
self.assertEqual(querydict_to_postdict(event.esp_event.POST), raw_event)

View File

@@ -1,12 +1,11 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
import hashlib
import hmac
from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings, tag
from django.utils.timezone import utc
from anymail.exceptions import AnymailConfigurationError
from anymail.signals import AnymailTrackingEvent
@@ -197,7 +196,7 @@ class MailgunTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "delivered")
self.assertEqual(event.timestamp, datetime(2018, 8, 12, 21, 17, 17, microsecond=153125, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2018, 8, 12, 21, 17, 17, microsecond=153125, tzinfo=timezone.utc))
self.assertEqual(event.message_id, "<20180812211713.1.DF5966851B4BAA99@example.org>")
# Note that Anymail uses the "token" as its normalized event_id:
self.assertEqual(event.event_id, "651869375b9df3c98fc15c4889b102119add1235c38fc92824")
@@ -513,7 +512,7 @@ class MailgunLegacyTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "delivered")
self.assertEqual(event.timestamp, datetime(2016, 4, 21, 17, 55, 30, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2016, 4, 21, 17, 55, 30, tzinfo=timezone.utc))
self.assertEqual(event.message_id, "<20160421175529.19495.89030.B3AE3728@example.com>")
self.assertEqual(event.event_id, "06c96bafc3f42a66b9edd546347a2fe18dc23461fe80dc52f0")
self.assertEqual(event.recipient, "recipient@example.com")
@@ -552,7 +551,7 @@ class MailgunLegacyTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "rejected")
self.assertEqual(event.timestamp, datetime(2016, 4, 21, 17, 55, 30, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2016, 4, 21, 17, 55, 30, tzinfo=timezone.utc))
self.assertEqual(event.message_id, "<20160421180324.70521.79375.96884DDB@example.com>")
self.assertEqual(event.event_id, "a3fe1fa1640349ac552b84ddde373014b4c41645830c8dd3fc")
self.assertEqual(event.recipient, "bounce@example.com")

View File

@@ -1,9 +1,8 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
from django.test import tag
from django.utils.timezone import utc
from anymail.signals import AnymailTrackingEvent
from anymail.webhooks.mailjet import MailjetTrackingWebhookView
@@ -44,7 +43,7 @@ class MailjetDeliveryTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "delivered")
self.assertEqual(event.timestamp, datetime(2017, 6, 22, 1, 5, 27, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2017, 6, 22, 1, 5, 27, tzinfo=timezone.utc))
self.assertEqual(event.esp_event, raw_events[0])
self.assertEqual(event.mta_response, "sent (250 2.0.0 OK 1498093527 a67bc12345def.22 - gsmtp)")
self.assertEqual(event.message_id, "12345678901234567") # converted to str (matching backend status)
@@ -251,7 +250,7 @@ class MailjetDeliveryTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "delivered")
self.assertEqual(event.timestamp, datetime(2017, 6, 22, 1, 5, 27, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2017, 6, 22, 1, 5, 27, tzinfo=timezone.utc))
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.mta_response, "sent (250 2.0.0 OK 1498093527 a67bc12345def.22 - gsmtp)")
self.assertEqual(event.message_id, "12345678901234567") # converted to str (matching backend status)

View File

@@ -2,13 +2,12 @@ import hashlib
import hmac
import json
from base64 import b64encode
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
from urllib.parse import urljoin
from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings, tag
from django.utils.timezone import utc
from anymail.signals import AnymailTrackingEvent
from anymail.webhooks.mandrill import MandrillCombinedWebhookView, MandrillTrackingWebhookView
@@ -166,7 +165,7 @@ class MandrillTrackingTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "sent")
self.assertEqual(event.timestamp, datetime(2016, 4, 19, 19, 47, 26, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2016, 4, 19, 19, 47, 26, tzinfo=timezone.utc))
self.assertEqual(event.esp_event, raw_events[0])
self.assertEqual(event.message_id, "abcdef012345789abcdef012345789")
self.assertEqual(event.recipient, "recipient@example.com")

View File

@@ -1,11 +1,10 @@
import json
import unittest
from base64 import b64encode
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
from django.test import tag
from django.utils.timezone import utc
from anymail.exceptions import AnymailConfigurationError
from anymail.signals import AnymailTrackingEvent
@@ -100,7 +99,7 @@ class PostalDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "bounced")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=utc))
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=timezone.utc))
self.assertEqual(event.message_id, 233843)
self.assertEqual(event.event_id, "0fcc831f-92b9-4e2b-97f2-d873abc77fab")
self.assertEqual(event.recipient, "bounce@example.com")
@@ -145,7 +144,7 @@ class PostalDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "deferred")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=utc))
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=timezone.utc))
self.assertEqual(event.message_id, 1564)
self.assertEqual(event.event_id, "0fcc831f-92b9-4e2b-97f2-d873abc77fab")
self.assertEqual(event.recipient, "deferred@example.com")
@@ -190,7 +189,7 @@ class PostalDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "queued")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=utc))
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=timezone.utc))
self.assertEqual(event.message_id, 1568)
self.assertEqual(event.event_id, "9be13015-2e54-456c-bf66-eacbe33da824")
self.assertEqual(event.recipient, "suppressed@example.com")
@@ -235,7 +234,7 @@ class PostalDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "failed")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=utc))
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=timezone.utc))
self.assertEqual(event.message_id, 1571)
self.assertEqual(event.event_id, "5fec5077-dae7-4989-94d5-e1963f3e9181")
self.assertEqual(event.recipient, "failed@example.com")
@@ -280,7 +279,7 @@ class PostalDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "delivered")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=utc))
self.assertEqual(event.timestamp, datetime.fromtimestamp(1606753101, tz=timezone.utc))
self.assertEqual(event.message_id, 1563)
self.assertEqual(event.recipient, "recipient@example.com")
self.assertEqual(event.tags, ["welcome-email"])

View File

@@ -1,9 +1,9 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
from django.test import tag
from django.utils.timezone import get_fixed_timezone, utc
from django.utils.timezone import get_fixed_timezone
from anymail.exceptions import AnymailConfigurationError
from anymail.signals import AnymailTrackingEvent
@@ -165,7 +165,7 @@ class PostmarkDeliveryTestCase(WebhookTestCase):
self.assertEqual(event.event_type, "clicked")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2017, 10, 25, 15, 21, 11, microsecond=906561,
tzinfo=utc))
tzinfo=timezone.utc))
self.assertEqual(event.message_id, "f4830d10-9c35-4f0c-bca3-3d9b459821f8")
self.assertEqual(event.recipient, "recipient@example.com")
self.assertEqual(event.user_agent, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) etc.")
@@ -247,7 +247,7 @@ class PostmarkDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "unsubscribed")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2022, 6, 5, 17, 17, 32, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2022, 6, 5, 17, 17, 32, tzinfo=timezone.utc))
self.assertEqual(event.message_id, "a4909a96-73d7-4c49-b148-a54522d3f7ac")
self.assertEqual(event.recipient, "john@example.com",)
self.assertEqual(event.reject_reason, "unsubscribed")
@@ -278,7 +278,7 @@ class PostmarkDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "subscribed")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2022, 6, 5, 17, 17, 32, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2022, 6, 5, 17, 17, 32, tzinfo=timezone.utc))
self.assertEqual(event.message_id, "a4909a96-73d7-4c49-b148-a54522d3f7ac")
self.assertEqual(event.recipient, "john@example.com",)
self.assertEqual(event.reject_reason, None)
@@ -309,7 +309,7 @@ class PostmarkDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "bounced")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2022, 6, 5, 17, 17, 32, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2022, 6, 5, 17, 17, 32, tzinfo=timezone.utc))
self.assertEqual(event.message_id, "b4cb783d-78ed-43f2-983b-63f55c712dc8")
self.assertEqual(event.recipient, "john@example.com",)
self.assertEqual(event.reject_reason, "bounced")

View File

@@ -1,9 +1,8 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
from django.test import tag
from django.utils.timezone import utc
from anymail.signals import AnymailTrackingEvent
from anymail.webhooks.sendgrid import SendGridTrackingWebhookView
@@ -43,7 +42,7 @@ class SendGridDeliveryTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "queued")
self.assertEqual(event.timestamp, datetime(2016, 4, 19, 19, 47, 26, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2016, 4, 19, 19, 47, 26, tzinfo=timezone.utc))
self.assertEqual(event.esp_event, raw_events[0])
self.assertEqual(event.message_id, "3c2f4df8-c6dd-4cd2-9b91-6582b81a0349")
self.assertEqual(event.event_id, "ZyjAM5rnQmuI1KFInHQ3Nw")
@@ -72,7 +71,7 @@ class SendGridDeliveryTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "delivered")
self.assertEqual(event.timestamp, datetime(2016, 4, 19, 19, 47, 30, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2016, 4, 19, 19, 47, 30, tzinfo=timezone.utc))
self.assertEqual(event.esp_event, raw_events[0])
self.assertEqual(event.message_id, "4ab185c2-0171-492f-9ce0-27de258efc99")
self.assertEqual(event.event_id, "nOSv8m0eTQ-vxvwNwt3fZQ")

View File

@@ -1,9 +1,8 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
from django.test import tag
from django.utils.timezone import utc
from anymail.signals import AnymailTrackingEvent
from anymail.webhooks.sendinblue import SendinBlueTrackingWebhookView
@@ -60,7 +59,7 @@ class SendinBlueDeliveryTestCase(WebhookTestCase):
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "queued")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2018, 3, 6, 19, 10, 23, microsecond=0, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2018, 3, 6, 19, 10, 23, microsecond=0, tzinfo=timezone.utc))
self.assertEqual(event.message_id, "<201803062010.27287306012@smtp-relay.mailin.fr>")
self.assertIsNone(event.event_id) # SendinBlue does not provide a unique event id
self.assertEqual(event.recipient, "recipient@example.com")

View File

@@ -1,5 +1,5 @@
import json
from datetime import date, datetime
from datetime import date, datetime, timezone
from decimal import Decimal
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
@@ -7,7 +7,7 @@ from email.mime.text import MIMEText
from django.core import mail
from django.test import override_settings, tag
from django.utils.timezone import get_fixed_timezone, override as override_current_timezone, utc
from django.utils.timezone import get_fixed_timezone, override as override_current_timezone
from anymail.exceptions import (
AnymailAPIError, AnymailConfigurationError, AnymailRecipientsRefused,
@@ -370,7 +370,7 @@ class SparkPostBackendAnymailFeatureTests(SparkPostBackendMockAPITestCase):
self.assertEqual(data["options"]["start_time"], "2016-03-04T05:06:07-08:00")
# Explicit UTC:
self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=utc)
self.message.send_at = datetime(2016, 3, 4, 5, 6, 7, tzinfo=timezone.utc)
self.message.send()
data = self.get_api_call_json()
self.assertEqual(data["options"]["start_time"], "2016-03-04T05:06:07+00:00")

View File

@@ -1,9 +1,8 @@
import json
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import ANY
from django.test import override_settings, tag
from django.utils.timezone import utc
from anymail.signals import AnymailTrackingEvent
from anymail.webhooks.sparkpost import SparkPostTrackingWebhookView
@@ -73,7 +72,7 @@ class SparkPostDeliveryTestCase(WebhookTestCase):
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "queued")
self.assertEqual(event.timestamp, datetime(2016, 2, 2, 19, 50, 00, tzinfo=utc))
self.assertEqual(event.timestamp, datetime(2016, 2, 2, 19, 50, 00, tzinfo=timezone.utc))
self.assertEqual(event.esp_event, raw_events[0])
self.assertEqual(event.message_id, "65832150921904138") # actually transmission_id
self.assertEqual(event.event_id, "92356927693813856")

View File

@@ -5,12 +5,14 @@ envlist =
# Factors: django-python-extras
# Test lint, docs, earliest/latest Django first, to catch most errors early...
lint
django40-py310-all
django41-py310-all
django20-py35-all
docs
# ... then test all the other supported combinations:
# Django 4.1: Python 3.8, 3.9, 3.10
django41-py{38,39,py38}-all
# Django 4.0: Python 3.8, 3.9, 3.10
django40-py{38,39,py38}-all
django40-py{38,39,310,py38}-all
# Django 3.2: Python 3.6, 3.7, 3.8, 3.9
django32-py{36,37,38,39,py38}-all
# Django 3.1: Python 3.6, 3.7, 3.8, 3.9 (added in 3.1.3)
@@ -39,6 +41,7 @@ deps =
django31: django~=3.1.0
django32: django~=3.2.0
django40: django~=4.0.0
django41: django~=4.1.0
djangoDev: https://github.com/django/django/tarball/main
old_urllib3: urllib3<1.25
extras =