[py3] Pass bytes as "msg" to smtplib.SMTP.sendmail() 3.26
authorDenis Laxalde <denis.laxalde@logilab.fr>
Tue, 06 Aug 2019 14:26:17 +0200
branch3.26
changeset 12719 9fb4a71f119d
parent 12708 db906fc4412d
child 12720 172f683a84f6
[py3] Pass bytes as "msg" to smtplib.SMTP.sendmail() When passing a unicode string to smtplib.SMTP.sendmail() as "msg" argument, there is an implicit bytes encoding using "ascii" encoding in python3. Of course this does not work if the string contains non-ASCII characters. In fact, config's sendmails method intent to pass bytes to smtplib.SMTP.sendmail() as it uses msg.as_string() method. Unfortunately, in python3, this method returns a unicode string whereas it returns a bytes string in python2; we thus fix this by calling as_bytes() method on python3. As there is no "as_bytes" method in python2, we need to handle python2 compatibility by hand and either call as_string() or as_bytes(). In testlib, where we mock smtplib.SMTP, we need to keep the "msg" argument of Email class (defined in testlib as well) a unicode string. Otherwise, it fails to be parsed by email.message_from_string() (from stdlib) if it is bytes on python3.
cubicweb/cwconfig.py
cubicweb/devtools/testlib.py
--- a/cubicweb/cwconfig.py	Wed Jul 24 13:39:52 2019 +0200
+++ b/cubicweb/cwconfig.py	Tue Aug 06 14:26:17 2019 +0200
@@ -192,7 +192,7 @@
 from threading import Lock
 from warnings import filterwarnings
 
-from six import text_type
+from six import PY2, text_type
 
 from logilab.common.decorators import cached, classproperty
 from logilab.common.deprecation import deprecated
@@ -1344,9 +1344,10 @@
                 if self.mode == 'test':
                     raise
                 return False
-            for msg, recipients in msgs:
+            for mimedoc, recipients in msgs:
+                msg = mimedoc.as_string() if PY2 else mimedoc.as_bytes()
                 try:
-                    smtp.sendmail(fromaddr, recipients, msg.as_string())
+                    smtp.sendmail(fromaddr, recipients, msg)
                 except Exception as ex:
                     self.exception("error sending mail to %s (%s)",
                                    recipients, ex)
--- a/cubicweb/devtools/testlib.py	Wed Jul 24 13:39:52 2019 +0200
+++ b/cubicweb/devtools/testlib.py	Tue Aug 06 14:26:17 2019 +0200
@@ -205,7 +205,7 @@
         pass
 
     def sendmail(self, fromaddr, recipients, msg):
-        MAILBOX.append(Email(fromaddr, recipients, msg))
+        MAILBOX.append(Email(fromaddr, recipients, msg.decode('utf-8')))
 
 
 cwconfig.SMTP = MockSMTP