summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/core/mail/message.py4
-rw-r--r--docs/releases/5.2.1.txt3
-rw-r--r--tests/mail/tests.py18
3 files changed, 23 insertions, 2 deletions
diff --git a/django/core/mail/message.py b/django/core/mail/message.py
index adcd9fc504..421e353bfa 100644
--- a/django/core/mail/message.py
+++ b/django/core/mail/message.py
@@ -191,8 +191,8 @@ class SafeMIMEMultipart(MIMEMixin, MIMEMultipart):
MIMEMultipart.__setitem__(self, name, val)
-EmailAlternative = namedtuple("Alternative", ["content", "mimetype"])
-EmailAttachment = namedtuple("Attachment", ["filename", "content", "mimetype"])
+EmailAlternative = namedtuple("EmailAlternative", ["content", "mimetype"])
+EmailAttachment = namedtuple("EmailAttachment", ["filename", "content", "mimetype"])
class EmailMessage:
diff --git a/docs/releases/5.2.1.txt b/docs/releases/5.2.1.txt
index 82df478d96..a79d61c60a 100644
--- a/docs/releases/5.2.1.txt
+++ b/docs/releases/5.2.1.txt
@@ -48,3 +48,6 @@ Bugfixes
* Fixed a regression in Django 5.2, introduced when fixing :cve:`2025-26699`,
where the :tfilter:`wordwrap` template filter did not preserve empty lines
between paragraphs after wrapping text (:ticket:`36341`).
+
+* Fixed a regression in Django 5.2 that caused a crash when serializing email
+ alternatives or attachments due to named tuple mismatches (:ticket:`36309`).
diff --git a/tests/mail/tests.py b/tests/mail/tests.py
index 3fb1a47bc7..301e589409 100644
--- a/tests/mail/tests.py
+++ b/tests/mail/tests.py
@@ -1,5 +1,6 @@
import mimetypes
import os
+import pickle
import shutil
import socket
import sys
@@ -654,6 +655,23 @@ class MailTests(MailTestsMixin, SimpleTestCase):
self.assertIn(html_content, msg.message().as_string())
+ def test_alternatives_and_attachment_serializable(self):
+ html_content = "<p>This is <strong>html</strong></p>"
+ mime_type = "text/html"
+
+ msg = EmailMultiAlternatives(alternatives=[(html_content, mime_type)])
+ msg.attach("test.txt", "This is plain text.", "plain/text")
+
+ # Alternatives and attachments can be serialized.
+ restored = pickle.loads(pickle.dumps(msg))
+
+ self.assertEqual(restored.subject, msg.subject)
+ self.assertEqual(restored.body, msg.body)
+ self.assertEqual(restored.from_email, msg.from_email)
+ self.assertEqual(restored.to, msg.to)
+ self.assertEqual(restored.alternatives, msg.alternatives)
+ self.assertEqual(restored.attachments, msg.attachments)
+
def test_none_body(self):
msg = EmailMessage("subject", None, "from@example.com", ["to@example.com"])
self.assertEqual(msg.body, "")