diff --git a/Lib/email/charset.py b/Lib/email/charset.py index 9e5ee67bfe6..a44b711aa4b 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -377,6 +377,8 @@ class Charset: """ # 7bit/8bit encodings return the string unchanged (module conversions) if self.body_encoding is BASE64: + if isinstance(string, str): + string = string.encode(self.output_charset) return email.base64mime.body_encode(string) elif self.body_encoding is QP: return email.quoprimime.body_encode(string) diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py index 6793df50c6c..44a47c54fcf 100644 --- a/Lib/email/test/test_email.py +++ b/Lib/email/test/test_email.py @@ -535,7 +535,7 @@ class TestEncoders(unittest.TestCase): # whose output character set is 7bit gets a transfer-encoding # of 7bit. eq = self.assertEqual - msg = MIMEText('\xca\xb8', _charset='euc-jp') + msg = MIMEText('文', _charset='euc-jp') eq(msg['content-transfer-encoding'], '7bit') @@ -1080,6 +1080,33 @@ class TestMIMEText(unittest.TestCase): eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + def test_7bit_input(self): + eq = self.assertEqual + msg = MIMEText('hello there', _charset='us-ascii') + eq(msg.get_charset().input_charset, 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + + def test_7bit_input_no_charset(self): + eq = self.assertEqual + msg = MIMEText('hello there') + eq(msg.get_charset(), 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + self.assertTrue('hello there' in msg.as_string()) + + def test_utf8_input(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + eq = self.assertEqual + msg = MIMEText(teststr, _charset='utf-8') + eq(msg.get_charset().output_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') + eq(msg.get_payload(decode=True), teststr.encode('utf-8')) + + @unittest.skip("can't fix because of backward compat in email5, " + "will fix in email6") + def test_utf8_input_no_charset(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + self.assertRaises(UnicodeEncodeError, MIMEText, teststr) + # Test complicated multipart/* messages diff --git a/Misc/NEWS b/Misc/NEWS index 68f36fcc930..4c60de3f223 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -398,6 +398,10 @@ C-API Library ------- +- Charset.body_encode now correctly handles base64 encoding by encoding + with the output_charset before calling base64mime.encode. Passes the + tests from 2.x issue 1368247. + - Issue #8845: sqlite3 Connection objects now have a read-only in_transaction attribute that is True iff there are uncommitted changes.