diff -r 28c04e954bb6 Lib/email/encoders.py --- a/Lib/email/encoders.py Tue Oct 29 22:25:55 2013 -0400 +++ b/Lib/email/encoders.py Wed Oct 30 22:56:58 2013 +0800 @@ -49,7 +49,7 @@ def encode_7or8bit(msg): """Set the Content-Transfer-Encoding header to 7bit or 8bit.""" - orig = msg.get_payload(decode=True) + orig = msg._payload if orig is None: # There's no payload. For backwards compatibility we use 7bit msg['Content-Transfer-Encoding'] = '7bit' diff -r 28c04e954bb6 Lib/email/generator.py --- a/Lib/email/generator.py Tue Oct 29 22:25:55 2013 -0400 +++ b/Lib/email/generator.py Wed Oct 30 22:56:58 2013 +0800 @@ -392,7 +392,11 @@ _encoded_EMPTY = b'' def write(self, s): - self._fp.write(s.encode('ascii', 'surrogateescape')) + try: + self._fp.write(s.encode('ascii', 'surrogateescape')) + except UnicodeEncodeError: + # Writing 8bit data to bytes container. + self._fp.write(s.encode('raw-unicode-escape')) def _new_buffer(self): return BytesIO() diff -r 28c04e954bb6 Lib/email/message.py --- a/Lib/email/message.py Tue Oct 29 22:25:55 2013 -0400 +++ b/Lib/email/message.py Wed Oct 30 22:56:58 2013 +0800 @@ -302,7 +302,10 @@ set_charset() for details. """ if isinstance(payload, bytes): - payload = payload.decode('ascii', 'surrogateescape') + if charset is not None: + payload = payload.decode(str(charset)) + else: + payload = payload.decode('ascii', 'surrogateescape') self._payload = payload if charset is not None: self.set_charset(charset) diff -r 28c04e954bb6 Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py Tue Oct 29 22:25:55 2013 -0400 +++ b/Lib/test/test_email/test_email.py Wed Oct 30 22:56:58 2013 +0800 @@ -702,6 +702,26 @@ w4kgdGVzdGFiYwo= """)) + def test_set_payload_with_8bit_data_and_charset_none(self): + str_data = 'АБВ' + bytes_data = str_data.encode('utf-8') + cs = Charset('utf-8') + cs.body_encoding = None + msg = Message() + for data in (str_data, bytes_data): + msg.set_payload(data, cs) + self.assertEqual(msg.as_string(), textwrap.dedent("""\ + MIME-Version: 1.0 + Content-Type: text/plain; charset="utf-8" + Content-Transfer-Encoding: 8bit + + АБВ""")) + self.assertEqual(msg.as_bytes(), + (b'MIME-Version: 1.0\n' + b'Content-Type: text/plain; charset="utf-8"\n' + b'Content-Transfer-Encoding: 8bit\n\n' + b'\\u0410\\u0411\\u0412')) + # Test the email.encoders module class TestEncoders(unittest.TestCase):