Opened 3 months ago

Last modified 2 months ago

#36478 closed Bug

EmailMessage handles utf-8 encoded text attachments differently in constructor vs property — at Version 1

Reported by: Mike Edmunds Owned by: Mike Edmunds
Component: Core (Mail) Version: 5.2
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Mike Edmunds)

Encoded text attachments set directly in the EmailMessage.attachments property are not processed like the same content passed to EmailMessage(attachments=...) or EmailMessage.attach(...).

#27007 added EmailMessage.attach() handling for text content encoded as utf-8 bytes. That code is also used for the attachments constructor argument, but not for attachments set directly on the object property:

    # Existing test: passes
    def test_attach_text_as_bytes(self):
        msg = EmailMessage()
        msg.attach("file.txt", b"file content\n")
        filename, content, mimetype = self.get_decoded_attachments(msg)[0]
        self.assertEqual(filename, "file.txt")
        self.assertEqual(content, "file content\n")
        self.assertEqual(mimetype, "text/plain")

    # New test: passes
    def test_attach_text_as_bytes_using_constructor(self):
        msg = EmailMessage(
            attachments=[EmailAttachment("file.txt", b"file content\n", "text/plain")]
        )
        filename, content, mimetype = self.get_decoded_attachments(msg)[0]
        self.assertEqual(filename, "file.txt")
        self.assertEqual(content, "file content\n")
        self.assertEqual(mimetype, "text/plain")

    # New test: AttributeError: 'bytes' object has no attribute 'encode'
    def test_attach_text_as_bytes_using_property(self):
        msg = EmailMessage()
        msg.attachments = [EmailAttachment("file.txt", b"file content\n", "text/plain")]
        filename, content, mimetype = self.get_decoded_attachments(msg)[0]
        self.assertEqual(filename, "file.txt")
        self.assertEqual(content, "file content\n")
        self.assertEqual(mimetype, "text/plain")

The second added test fails with AttributeError: 'bytes' object has no attribute 'encode deep in SafeMIMEText.

The EmailMessage documentation implies that the second and third tests should be equivalent.

(#27007 also added a fallback to application/octet-stream for non-utf-8 text content, but didn't include a test case for that behavior.)

See also https://github.com/django/django/pull/18966#discussion_r2154081996

Change History (1)

comment:1 by Mike Edmunds, 3 months ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top