From 6cfbdc6cfbbdbec9ba4119c3152a78e404072118 Mon Sep 17 00:00:00 2001 From: lafe3402 Date: Sat, 13 Jan 2018 18:13:07 -0500 Subject: [PATCH 01/11] bpo-28879: add Date header to send_message as per RFC5322 --- Doc/library/smtplib.rst | 17 +++-- Lib/smtplib.py | 4 ++ Lib/test/test_smtplib.py | 66 ++++++++++--------- .../2018-01-13-15-52-00.bpo-28879.aW2gj0.rst | 2 + 4 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index b3cc60357f554a..509eedbab72e8c 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -522,12 +522,17 @@ An :class:`SMTP` instance has the following methods: specified in :rfc:`5322`\: *from_addr* is set to the :mailheader:`Sender` field if it is present, and otherwise to the :mailheader:`From` field. *to_addrs* combines the values (if any) of the :mailheader:`To`, - :mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If exactly one - set of :mailheader:`Resent-*` headers appear in the message, the regular - headers are ignored and the :mailheader:`Resent-*` headers are used instead. - If the message contains more than one set of :mailheader:`Resent-*` headers, - a :exc:`ValueError` is raised, since there is no way to unambiguously detect - the most recent set of :mailheader:`Resent-` headers. + :mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If there's no + :mailheader:`Date` header inside the message, ``send_message`` will add one to the data. + If exactly one set of :mailheader:`Resent-*` headers appear in the message, + the regular headers are ignored and the :mailheader:`Resent-*` headers are + used instead. If the message contains more than one set of + :mailheader:`Resent-*` headers, a :exc:`ValueError` is raised, since there + is no way to unambiguously detect the most recent set of + :mailheader:`Resent-` headers. + + .. versionchanged:: 3.2 + Support to add :mailheader:`Date` header to the message if one does not exist. ``send_message`` serializes *msg* using :class:`~email.generator.BytesGenerator` with ``\r\n`` as the *linesep*, and diff --git a/Lib/smtplib.py b/Lib/smtplib.py index e2dbbbcf2e6d16..5e2d3f4b02ca1f 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -932,6 +932,10 @@ def send_message(self, msg, from_addr=None, to_addrs=None, header_prefix = 'Resent-' else: raise ValueError("message has more than one 'Resent-' header block") + + # RFC 5322 section 3.6, 4th Paragraph + if msg.get('Date', None) is None: + msg['Date'] = email.utils.formatdate() if from_addr is None: # Prefer the sender field per RFC 2822:3.6.2. from_addr = (msg[header_prefix + 'Sender'] diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 7816ed34886e95..31af316c88cfe1 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -23,7 +23,7 @@ from test.support import hashlib_helper from test.support import socket_helper from test.support import threading_helper -from unittest.mock import Mock +from unittest.mock import Mock, patch HOST = socket_helper.HOST @@ -1342,36 +1342,40 @@ def test_send_unicode_with_SMTPUTF8_via_low_level_API(self): self.assertEqual(self.serv.last_rcpt_options, []) def test_send_message_uses_smtputf8_if_addrs_non_ascii(self): - msg = EmailMessage() - msg['From'] = "Páolo " - msg['To'] = 'Dinsdale' - msg['Subject'] = 'Nudge nudge, wink, wink \u1F609' - # XXX I don't know why I need two \n's here, but this is an existing - # bug (if it is one) and not a problem with the new functionality. - msg.set_content("oh là là, know what I mean, know what I mean?\n\n") - # XXX smtpd converts received /r/n to /n, so we can't easily test that - # we are successfully sending /r/n :(. - expected = textwrap.dedent("""\ - From: Páolo - To: Dinsdale - Subject: Nudge nudge, wink, wink \u1F609 - Content-Type: text/plain; charset="utf-8" - Content-Transfer-Encoding: 8bit - MIME-Version: 1.0 - - oh là là, know what I mean, know what I mean? - """) - smtp = smtplib.SMTP( - HOST, self.port, local_hostname='localhost', - timeout=support.LOOPBACK_TIMEOUT) - self.addCleanup(smtp.close) - self.assertEqual(smtp.send_message(msg), {}) - self.assertEqual(self.serv.last_mailfrom, 'főo@bar.com') - self.assertEqual(self.serv.last_rcpttos, ['Dinsdale']) - self.assertEqual(self.serv.last_message.decode(), expected) - self.assertIn('BODY=8BITMIME', self.serv.last_mail_options) - self.assertIn('SMTPUTF8', self.serv.last_mail_options) - self.assertEqual(self.serv.last_rcpt_options, []) + expected_date = "Thu, 19 Mar 2020 00:59:43 -0000" + with patch("email.utils.formatdate") as date_mock: + date_mock.return_value = expected_date + msg = EmailMessage() + msg['From'] = "Páolo " + msg['To'] = 'Dinsdale' + msg['Subject'] = 'Nudge nudge, wink, wink \u1F609' + # XXX I don't know why I need two \n's here, but this is an existing + # bug (if it is one) and not a problem with the new functionality. + msg.set_content("oh là là, know what I mean, know what I mean?\n\n") + # XXX smtpd converts received /r/n to /n, so we can't easily test that + # we are successfully sending /r/n :(. + expected = textwrap.dedent("""\ + From: Páolo + To: Dinsdale + Subject: Nudge nudge, wink, wink \u1F609 + Content-Type: text/plain; charset="utf-8" + Content-Transfer-Encoding: 8bit + MIME-Version: 1.0 + Date: {} + + oh là là, know what I mean, know what I mean? + """.format(expected_date)) + smtp = smtplib.SMTP( + HOST, self.port, local_hostname='localhost', + timeout=support.LOOPBACK_TIMEOUT) + self.addCleanup(smtp.close) + self.assertEqual(smtp.send_message(msg), {}) + self.assertEqual(self.serv.last_mailfrom, 'főo@bar.com') + self.assertEqual(self.serv.last_rcpttos, ['Dinsdale']) + self.assertEqual(self.serv.last_message.decode(), expected) + self.assertIn('BODY=8BITMIME', self.serv.last_mail_options) + self.assertIn('SMTPUTF8', self.serv.last_mail_options) + self.assertEqual(self.serv.last_rcpt_options, []) EXPECTED_RESPONSE = encode_base64(b'\0psu\0doesnotexist', eol='') diff --git a/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst b/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst new file mode 100644 index 00000000000000..3cd194ba82f5f4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst @@ -0,0 +1,2 @@ +Fix ``smtplib.send_message`` to add a ``Date`` header if it is missing as per +RFC5322. \ No newline at end of file From 5ffc0989ac66902bb1332a023b7ed2fb9bcc5520 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 09:39:17 +0200 Subject: [PATCH 02/11] add patch --- Lib/test/test_smtplib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index d2218d30bd4d76..5b664d093ab8eb 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -23,7 +23,7 @@ from test.support import threading_helper from test.support import asyncore from test.support import smtpd -from unittest.mock import Mock +from unittest.mock import Mock, patch support.requires_working_socket(module=True) From 4c2353c3ed38e77a5029a96f5b316993e5906430 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 09:51:52 +0200 Subject: [PATCH 03/11] update blurb --- ...79.aW2gj0.rst => 2025-07-20-09-51-25.bpo-28879.SLDgcy.rst} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename Misc/NEWS.d/next/Library/{2018-01-13-15-52-00.bpo-28879.aW2gj0.rst => 2025-07-20-09-51-25.bpo-28879.SLDgcy.rst} (73%) diff --git a/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst b/Misc/NEWS.d/next/Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst similarity index 73% rename from Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst rename to Misc/NEWS.d/next/Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst index 3cd194ba82f5f4..c69820f4e53648 100644 --- a/Misc/NEWS.d/next/Library/2018-01-13-15-52-00.bpo-28879.aW2gj0.rst +++ b/Misc/NEWS.d/next/Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst @@ -1,2 +1,2 @@ -Fix ``smtplib.send_message`` to add a ``Date`` header if it is missing as per -RFC5322. \ No newline at end of file +Fix ``smtplib.send_message`` to add a ``Date`` header if it is missing as +per RFC5322. From a4bc9c7c5a1d35043795719278dcafb79eeeb888 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 13:06:21 +0200 Subject: [PATCH 04/11] update rst --- Doc/library/smtplib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index 8762d2710253b3..6cd9db3a86e0c8 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -519,7 +519,7 @@ An :class:`SMTP` instance has the following methods: is no way to unambiguously detect the most recent set of :mailheader:`Resent-` headers. - .. versionchanged:: 3.2 + .. versionchanged:: 3.14 Support to add :mailheader:`Date` header to the message if one does not exist. ``send_message`` serializes *msg* using From f960ab26effb4efb73af011b3208fdf0aa7f5903 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 13:06:29 +0200 Subject: [PATCH 05/11] update rst --- Doc/library/smtplib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index 6cd9db3a86e0c8..6553487f27fdd3 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -519,7 +519,7 @@ An :class:`SMTP` instance has the following methods: is no way to unambiguously detect the most recent set of :mailheader:`Resent-` headers. - .. versionchanged:: 3.14 + .. versionchanged:: 3.15 Support to add :mailheader:`Date` header to the message if one does not exist. ``send_message`` serializes *msg* using From 0e6ec22932e46209a6e6c6d63a76696dd419ebb0 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 13:55:16 +0200 Subject: [PATCH 06/11] update tests to not patch date --- Lib/smtplib.py | 3 +- Lib/test/test_smtplib.py | 79 ++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 53da9bd5378321..ddbc34458383cf 100644 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -938,7 +938,8 @@ def send_message(self, msg, from_addr=None, to_addrs=None, # RFC 5322 section 3.6, 4th Paragraph if msg.get('Date', None) is None: - msg['Date'] = email.utils.formatdate() + # localtime: RFC 5322 section 3.3 4th Paragraph + msg['Date'] = email.utils.formatdate(localtime=True) if from_addr is None: # Prefer the sender field per RFC 2822:3.6.2. from_addr = (msg[header_prefix + 'Sender'] diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 5b664d093ab8eb..4f43baf52a1680 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -23,7 +23,7 @@ from test.support import threading_helper from test.support import asyncore from test.support import smtpd -from unittest.mock import Mock, patch +from unittest.mock import Mock support.requires_working_socket(module=True) @@ -1393,6 +1393,11 @@ class SMTPUTF8SimTests(unittest.TestCase): maxDiff = None + def _is_local(self, date: str) -> bool: + dt = email.utils.parsedate_to_datetime(date) + local_offset = dt.now().astimezone().utcoffset() + return dt.utcoffset() == local_offset + def setUp(self): self.thread_key = threading_helper.threading_setup() self.real_getfqdn = socket.getfqdn @@ -1468,40 +1473,44 @@ def test_send_unicode_with_SMTPUTF8_via_low_level_API(self): self.assertEqual(self.serv.last_rcpt_options, []) def test_send_message_uses_smtputf8_if_addrs_non_ascii(self): - expected_date = "Thu, 19 Mar 2020 00:59:43 -0000" - with patch("email.utils.formatdate") as date_mock: - date_mock.return_value = expected_date - msg = EmailMessage() - msg['From'] = "Páolo " - msg['To'] = 'Dinsdale' - msg['Subject'] = 'Nudge nudge, wink, wink \u1F609' - # XXX I don't know why I need two \n's here, but this is an existing - # bug (if it is one) and not a problem with the new functionality. - msg.set_content("oh là là, know what I mean, know what I mean?\n\n") - # XXX smtpd converts received /r/n to /n, so we can't easily test that - # we are successfully sending /r/n :(. - expected = textwrap.dedent("""\ - From: Páolo - To: Dinsdale - Subject: Nudge nudge, wink, wink \u1F609 - Content-Type: text/plain; charset="utf-8" - Content-Transfer-Encoding: 8bit - MIME-Version: 1.0 - Date: {} - - oh là là, know what I mean, know what I mean? - """.format(expected_date)) - smtp = smtplib.SMTP( - HOST, self.port, local_hostname='localhost', - timeout=support.LOOPBACK_TIMEOUT) - self.addCleanup(smtp.close) - self.assertEqual(smtp.send_message(msg), {}) - self.assertEqual(self.serv.last_mailfrom, 'főo@bar.com') - self.assertEqual(self.serv.last_rcpttos, ['Dinsdale']) - self.assertEqual(self.serv.last_message.decode(), expected) - self.assertIn('BODY=8BITMIME', self.serv.last_mail_options) - self.assertIn('SMTPUTF8', self.serv.last_mail_options) - self.assertEqual(self.serv.last_rcpt_options, []) + msg = EmailMessage() + msg['From'] = "Páolo " + msg['To'] = 'Dinsdale' + msg['Subject'] = 'Nudge nudge, wink, wink \u1F609' + # XXX I don't know why I need two \n's here, but this is an existing + # bug (if it is one) and not a problem with the new functionality. + msg.set_content("oh là là, know what I mean, know what I mean?\n\n") + # XXX smtpd converts received /r/n to /n, so we can't easily test that + # we are successfully sending /r/n :(. + smtp = smtplib.SMTP( + HOST, self.port, local_hostname='localhost', + timeout=support.LOOPBACK_TIMEOUT) + self.addCleanup(smtp.close) + self.assertEqual(smtp.send_message(msg), {}) + self.assertEqual(self.serv.last_mailfrom, 'főo@bar.com') + self.assertEqual(self.serv.last_rcpttos, ['Dinsdale']) + + last_message = self.serv.last_message.decode() + date = email.message_from_string(last_message)['Date'] + # asserts RFC 5322 section 3.3 4th Paragraph + self.assertTrue(self._is_local(date)) + + expected = textwrap.dedent("""\ + From: Páolo + To: Dinsdale + Subject: Nudge nudge, wink, wink \u1F609 + Content-Type: text/plain; charset="utf-8" + Content-Transfer-Encoding: 8bit + MIME-Version: 1.0 + Date: {} + + oh là là, know what I mean, know what I mean? + """.format(date)) + + self.assertEqual(last_message, expected) + self.assertIn('BODY=8BITMIME', self.serv.last_mail_options) + self.assertIn('SMTPUTF8', self.serv.last_mail_options) + self.assertEqual(self.serv.last_rcpt_options, []) EXPECTED_RESPONSE = encode_base64(b'\0psu\0doesnotexist', eol='') From be69865fc6411a469c4b78540e72132d87f8be88 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 14:02:29 +0200 Subject: [PATCH 07/11] reorder assertions for readability --- Lib/test/test_smtplib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 4f43baf52a1680..6e2af1f23707fd 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -1487,8 +1487,6 @@ def test_send_message_uses_smtputf8_if_addrs_non_ascii(self): timeout=support.LOOPBACK_TIMEOUT) self.addCleanup(smtp.close) self.assertEqual(smtp.send_message(msg), {}) - self.assertEqual(self.serv.last_mailfrom, 'főo@bar.com') - self.assertEqual(self.serv.last_rcpttos, ['Dinsdale']) last_message = self.serv.last_message.decode() date = email.message_from_string(last_message)['Date'] @@ -1507,6 +1505,8 @@ def test_send_message_uses_smtputf8_if_addrs_non_ascii(self): oh là là, know what I mean, know what I mean? """.format(date)) + self.assertEqual(self.serv.last_mailfrom, 'főo@bar.com') + self.assertEqual(self.serv.last_rcpttos, ['Dinsdale']) self.assertEqual(last_message, expected) self.assertIn('BODY=8BITMIME', self.serv.last_mail_options) self.assertIn('SMTPUTF8', self.serv.last_mail_options) From 3a8abdd26ee3f1d8e41c7e61576270d8dd6b8980 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 14:24:16 +0200 Subject: [PATCH 08/11] . --- Lib/smtplib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py index ddbc34458383cf..99aad1d549bd30 100644 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -938,7 +938,7 @@ def send_message(self, msg, from_addr=None, to_addrs=None, # RFC 5322 section 3.6, 4th Paragraph if msg.get('Date', None) is None: - # localtime: RFC 5322 section 3.3 4th Paragraph + # localtime: RFC 5322 section 3.3, 4th Paragraph msg['Date'] = email.utils.formatdate(localtime=True) if from_addr is None: # Prefer the sender field per RFC 2822:3.6.2. From 00c870a3285a4b441fefad3b0307fcf515a11395 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 16:39:34 +0200 Subject: [PATCH 09/11] use support.run_with_tz --- Doc/library/smtplib.rst | 2 +- Lib/test/test_smtplib.py | 12 ++++++------ .../Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index 6553487f27fdd3..344514a8d434cf 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -519,7 +519,7 @@ An :class:`SMTP` instance has the following methods: is no way to unambiguously detect the most recent set of :mailheader:`Resent-` headers. - .. versionchanged:: 3.15 + .. versionchanged:: next Support to add :mailheader:`Date` header to the message if one does not exist. ``send_message`` serializes *msg* using diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 6e2af1f23707fd..3f96d3927e7892 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -26,6 +26,7 @@ from unittest.mock import Mock + support.requires_working_socket(module=True) HOST = socket_helper.HOST @@ -1393,11 +1394,6 @@ class SMTPUTF8SimTests(unittest.TestCase): maxDiff = None - def _is_local(self, date: str) -> bool: - dt = email.utils.parsedate_to_datetime(date) - local_offset = dt.now().astimezone().utcoffset() - return dt.utcoffset() == local_offset - def setUp(self): self.thread_key = threading_helper.threading_setup() self.real_getfqdn = socket.getfqdn @@ -1472,6 +1468,7 @@ def test_send_unicode_with_SMTPUTF8_via_low_level_API(self): self.assertIn('SMTPUTF8', self.serv.last_mail_options) self.assertEqual(self.serv.last_rcpt_options, []) + @support.run_with_tz('UTC-2') def test_send_message_uses_smtputf8_if_addrs_non_ascii(self): msg = EmailMessage() msg['From'] = "Páolo " @@ -1491,7 +1488,10 @@ def test_send_message_uses_smtputf8_if_addrs_non_ascii(self): last_message = self.serv.last_message.decode() date = email.message_from_string(last_message)['Date'] # asserts RFC 5322 section 3.3 4th Paragraph - self.assertTrue(self._is_local(date)) + self.assertEqual( + email.utils.parsedate_to_datetime(date).tzname(), + "UTC+02:00" + ) expected = textwrap.dedent("""\ From: Páolo diff --git a/Misc/NEWS.d/next/Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst b/Misc/NEWS.d/next/Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst index c69820f4e53648..f3fd71b58d89e1 100644 --- a/Misc/NEWS.d/next/Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst +++ b/Misc/NEWS.d/next/Library/2025-07-20-09-51-25.bpo-28879.SLDgcy.rst @@ -1,2 +1,2 @@ Fix ``smtplib.send_message`` to add a ``Date`` header if it is missing as -per RFC5322. +per :rfc:`5322`. From 6a5188e56a18778c0214c27a06f37379c6b6b43d Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 16:43:52 +0200 Subject: [PATCH 10/11] remove empty line --- Lib/test/test_smtplib.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 3f96d3927e7892..9d30fc4c209fcb 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -26,7 +26,6 @@ from unittest.mock import Mock - support.requires_working_socket(module=True) HOST = socket_helper.HOST From bcfe9d2c718055a875b1d5fbfb0ad12a673b8c46 Mon Sep 17 00:00:00 2001 From: ynir3 Date: Sun, 20 Jul 2025 16:48:35 +0200 Subject: [PATCH 11/11] use 02 syntax --- Lib/test/test_smtplib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 9d30fc4c209fcb..d364851ef8e7d8 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -1467,7 +1467,7 @@ def test_send_unicode_with_SMTPUTF8_via_low_level_API(self): self.assertIn('SMTPUTF8', self.serv.last_mail_options) self.assertEqual(self.serv.last_rcpt_options, []) - @support.run_with_tz('UTC-2') + @support.run_with_tz('UTC-02') def test_send_message_uses_smtputf8_if_addrs_non_ascii(self): msg = EmailMessage() msg['From'] = "Páolo " pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy