diff -r e27684eed3b6 Lib/email/generator.py --- a/Lib/email/generator.py Tue Nov 26 19:24:01 2013 -0600 +++ b/Lib/email/generator.py Wed Nov 27 16:46:47 2013 +0800 @@ -11,6 +11,7 @@ import time import random import warnings +import copy from io import StringIO, BytesIO from email._policybase import compat32 @@ -225,9 +226,14 @@ if _has_surrogates(msg._payload): charset = msg.get_param('charset') if charset is not None: - del msg['content-transfer-encoding'] - msg.set_payload(payload, charset) - payload = msg.get_payload() + orig_msg = copy.copy(msg) + try: + # Downcast 8bit data to 7bit data + del msg['content-transfer-encoding'] + msg.set_payload(payload, charset) + payload = msg.get_payload() + finally: + msg = orig_msg if self._mangle_from_: payload = fcre.sub('>From ', payload) self._write_lines(payload) diff -r e27684eed3b6 Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py Tue Nov 26 19:24:01 2013 -0600 +++ b/Lib/test/test_email/test_email.py Wed Nov 27 16:46:47 2013 +0800 @@ -3743,6 +3743,16 @@ email.generator.Generator(out).flatten(msg) self.assertEqual(out.getvalue(), self.non_latin_bin_msg_as7bit_wrapped) + def string_generator_should_not_mutate_message_when_handling_8bit(self): + msg = email.message_from_bytes(self.non_latin_bin_msg) + out = BytesIO() + BytesGenerator(out).flatten(msg) + orig_value = out.getvalue() + Generator(StringIO()).flatten(msg) + out = BytesIO() + BytesGenerator(out).flatten(msg) + self.assertEqual(out.getvalue(), orig_value) + def test_bytes_generator_with_unix_from(self): # The unixfrom contains a current date, so we can't check it # literally. Just make sure the first word is 'From' and the