diff --git a/Lib/email/contentmanager.py b/Lib/email/contentmanager.py index c0090af716575d7..9815e6a71c076b0 100644 --- a/Lib/email/contentmanager.py +++ b/Lib/email/contentmanager.py @@ -231,9 +231,9 @@ def set_bytes_content(msg, data, maintype, subtype, cte='base64', data = binascii.b2a_qp(data, istext=False, header=False, quotetabs=True) data = data.decode('ascii') elif cte == '7bit': - data = data.decode('ascii') + data = str(data, 'ascii') elif cte in ('8bit', 'binary'): - data = data.decode('ascii', 'surrogateescape') + data = str(data, 'ascii', 'surrogateescape') msg.set_payload(data) msg['Content-Transfer-Encoding'] = cte _finalize_set(msg, disposition, filename, cid, params) diff --git a/Lib/test/test_email/test_contentmanager.py b/Lib/test/test_email/test_contentmanager.py index 3115941f8703194..d7e098a0e2b55e7 100644 --- a/Lib/test/test_email/test_contentmanager.py +++ b/Lib/test/test_email/test_contentmanager.py @@ -848,6 +848,29 @@ def test_set_content_bytes_cte_7bit(self): ASCII-only message. """)) + def test_set_byteslike_content_with_unencoded_cte(self): + for cte in ('7bit', '8bit', 'binary'): + content = (b'ASCII-only message.\n' if cte == '7bit' else + b'non-ASCII \xa7\xff message.\r\n') + for buffer_type in (bytes, bytearray, memoryview): + with self.subTest(cte=cte, buffer_type=buffer_type): + m = self._make_message() + m.set_content(buffer_type(content), + maintype='application', + subtype='octet-stream', cte=cte) + self.assertEqual(m['Content-Transfer-Encoding'], cte) + self.assertEqual(m.get_payload(decode=True), content) + self.assertEqual(m.get_content(), content) + + def test_set_byteslike_non_ascii_with_cte_7bit_raises(self): + for buffer_type in (bytes, bytearray, memoryview): + with self.subTest(buffer_type=buffer_type): + m = self._make_message() + with self.assertRaises(UnicodeDecodeError): + m.set_content(buffer_type(b'non-ASCII \xa7\xff message'), + maintype='application', + subtype='octet-stream', cte='7bit') + content_object_params = { 'text_plain': ('content', ()), 'text_html': ('content', ('html',)), diff --git a/Misc/NEWS.d/next/Library/2026-10-20-00-00-00.gh-issue-159858.CQw9me.rst b/Misc/NEWS.d/next/Library/2026-10-20-00-00-00.gh-issue-159858.CQw9me.rst new file mode 100644 index 000000000000000..65fc880be4bba84 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-20-00-00-00.gh-issue-159858.CQw9me.rst @@ -0,0 +1,3 @@ +Fix :meth:`email.message.EmailMessage.set_content` raising +:exc:`AttributeError` for :class:`memoryview` payloads with the ``7bit``, +``8bit``, or ``binary`` content transfer encoding.