[Python-checkins] r81660 - in python/branches/py3k: Lib/email/charset.py Lib/email/test/test_email.py Misc/NEWS

r.david.murray python-checkins at python.org
Thu Jun 3 03:58:29 CEST 2010


Author: r.david.murray
Date: Thu Jun  3 03:58:28 2010
New Revision: 81660

Log:
Fix Charset.body_encode to encode to output_charset before calling base64mime.

This means that what gets encoded in base64 is the encoded version of the
unicode payload.  This bug was revealed by a forward port of the tests from
Issue 1368247, but the fix was completely different.

Note that the merge is only of the tests, the doc changes were inappropriate
since email5 expects unicode, not bytes.  I'm also not convinced that
quopri works correctly in email5, but that's a different issue.

Merged revisions 81658 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r81658 | r.david.murray | 2010-06-02 18:03:15 -0400 (Wed, 02 Jun 2010) | 9 lines
  
  #1368247: make set_charset/MIMEText automatically encode unicode _payload.
  
  Fixes (mysterious, to the end user) UnicodeErrors when using utf-8 as
  the charset and unicode as the _text argument.  Also makes the way in
  which unicode gets encoded to quoted printable for other charsets more
  sane (it only worked by accident previously).  The _payload now is encoded
  to the charset.output_charset if it is unicode.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/email/charset.py
   python/branches/py3k/Lib/email/test/test_email.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/email/charset.py
==============================================================================
--- python/branches/py3k/Lib/email/charset.py	(original)
+++ python/branches/py3k/Lib/email/charset.py	Thu Jun  3 03:58:28 2010
@@ -377,6 +377,8 @@
         """
         # 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)

Modified: python/branches/py3k/Lib/email/test/test_email.py
==============================================================================
--- python/branches/py3k/Lib/email/test/test_email.py	(original)
+++ python/branches/py3k/Lib/email/test/test_email.py	Thu Jun  3 03:58:28 2010
@@ -535,7 +535,7 @@
         # 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 @@
         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

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun  3 03:58:28 2010
@@ -398,6 +398,10 @@
 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.
 


More information about the Python-checkins mailing list