Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.6.x] Worked around a bug in python 3.3.3. Refs #21093

Backport of 280c1a6 from master.
  • Loading branch information...
commit ed167e53a52af22a8dce229696184b0d87a88a78 1 parent 35a447a
Florian Apolloner authored December 28, 2013
22  django/core/mail/message.py
@@ -21,7 +21,9 @@
21 21
 
22 22
 # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from
23 23
 # some spam filters.
24  
-Charset.add_charset('utf-8', Charset.SHORTEST, None, 'utf-8')
  24
+utf8_charset = Charset.Charset('utf-8')
  25
+utf8_charset.body_encoding = None  # Python defaults to BASE64
  26
+
25 27
 
26 28
 # Default MIME type to use on attachments (if it is not explicitly given
27 29
 # and cannot be guessed).
@@ -150,7 +152,23 @@ class SafeMIMEText(MIMEMixin, MIMEText):
150 152
 
151 153
     def __init__(self, text, subtype, charset):
152 154
         self.encoding = charset
153  
-        MIMEText.__init__(self, text, subtype, charset)
  155
+        if charset == 'utf-8':
  156
+            # Unfortunately, Python doesn't support setting a Charset instance
  157
+            # as MIMEText init parameter (http://bugs.python.org/issue16324).
  158
+            # We do it manually and trigger re-encoding of the payload.
  159
+            MIMEText.__init__(self, text, subtype, None)
  160
+            del self['Content-Transfer-Encoding']
  161
+            # Work around a bug in python 3.3.3 [sic], see
  162
+            # http://bugs.python.org/issue19063 for details.
  163
+            if sys.version_info[:3] == (3, 3, 3):
  164
+                payload = text.encode(utf8_charset.output_charset)
  165
+                self._payload = payload.decode('ascii', 'surrogateescape')
  166
+                self.set_charset(utf8_charset)
  167
+            else:
  168
+                self.set_payload(text, utf8_charset)
  169
+            self.replace_header('Content-Type', 'text/%s; charset="%s"' % (subtype, charset))
  170
+        else:
  171
+            MIMEText.__init__(self, text, subtype, charset)
154 172
 
155 173
     def __setitem__(self, name, val):
156 174
         name, val = forbid_multi_line_headers(name, val, self.encoding)
4  tests/mail/tests.py
@@ -460,7 +460,7 @@ def test_message_cc_header(self):
460 460
         email = EmailMessage('Subject', 'Content', 'from@example.com', ['to@example.com'], cc=['cc@example.com'])
461 461
         mail.get_connection().send_messages([email])
462 462
         message = self.get_the_message()
463  
-        self.assertStartsWith(message.as_string(), 'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nCc: cc@example.com\nDate: ')
  463
+        self.assertStartsWith(message.as_string(), 'MIME-Version: 1.0\nContent-Type: text/plain; charset="utf-8"\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nCc: cc@example.com\nDate: ')
464 464
 
465 465
     def test_idn_send(self):
466 466
         """
@@ -618,7 +618,7 @@ def test_console_stream_kwarg(self):
618 618
         s = StringIO()
619 619
         connection = mail.get_connection('django.core.mail.backends.console.EmailBackend', stream=s)
620 620
         send_mail('Subject', 'Content', 'from@example.com', ['to@example.com'], connection=connection)
621  
-        self.assertTrue(s.getvalue().startswith('Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nDate: '))
  621
+        self.assertTrue(s.getvalue().startswith('MIME-Version: 1.0\nContent-Type: text/plain; charset="utf-8"\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nDate: '))
622 622
 
623 623
 
624 624
 class FakeSMTPServer(smtpd.SMTPServer, threading.Thread):

0 notes on commit ed167e5

Please sign in to comment.
Something went wrong with that request. Please try again.