From 0913b216b9aeddecc10696a8003bd0a310efda18 Mon Sep 17 00:00:00 2001 From: lyschoening Date: Tue, 16 Sep 2014 11:39:01 +0200 Subject: [PATCH] Fix issue sending unicode messages in Python 3 Connection.send() now uses email.message.Message.as_bytes() in Python 3, and email.message.Message.as_string() in Python 2. --- flask_mail.py | 15 ++++++++++++--- tests.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/flask_mail.py b/flask_mail.py index 9cd9732..52faf58 100644 --- a/flask_mail.py +++ b/flask_mail.py @@ -183,7 +183,7 @@ def send(self, message, envelope_from=None): if self.host: self.host.sendmail(sanitize_address(envelope_from or message.sender), list(sanitize_addresses(message.send_to)), - message.as_string(), + message.as_bytes() if PY3 else message.as_string(), message.mail_options, message.rcpt_options) @@ -298,7 +298,7 @@ def _mimetext(self, text, subtype='plain'): charset = self.charset or 'utf-8' return MIMEText(text, _subtype=subtype, _charset=charset) - def as_string(self): + def _message(self): """Creates the email""" encoding = self.charset or 'utf-8' @@ -364,11 +364,20 @@ def as_string(self): if message_policy: msg.policy = message_policy - return msg.as_string() + return msg + + def as_string(self): + return self._message().as_string() + + def as_bytes(self): + return self._message().as_bytes() def __str__(self): return self.as_string() + def __bytes__(self): + return self.as_bytes() + def has_bad_headers(self): """Checks for bad headers i.e. newlines in subject, sender or recipients. RFC5322: Allows multiline CRLF with trailing whitespace (FWS) in headers diff --git a/tests.py b/tests.py index e2f4790..bc0bb7c 100644 --- a/tests.py +++ b/tests.py @@ -13,7 +13,7 @@ from email import charset from flask import Flask -from flask_mail import Mail, Message, BadHeaderError, sanitize_address +from flask_mail import Mail, Message, BadHeaderError, sanitize_address, PY3 from speaklater import make_lazy_string @@ -597,10 +597,11 @@ def test_sendmail_with_ascii_recipient(self): recipients=["to@example.com"], body="testing") conn.send(msg) + host.sendmail.assert_called_once_with( "from@example.com", ["to@example.com"], - msg.as_string(), + msg.as_bytes() if PY3 else msg.as_string(), msg.mail_options, msg.rcpt_options ) @@ -613,10 +614,46 @@ def test_sendmail_with_non_ascii_recipient(self): recipients=[u'ÄÜÖ → ✓ '], body="testing") conn.send(msg) + host.sendmail.assert_called_once_with( "from@example.com", ["=?utf-8?b?w4TDnMOWIOKGkiDinJM=?= "], - msg.as_string(), + msg.as_bytes() if PY3 else msg.as_string(), + msg.mail_options, + msg.rcpt_options + ) + + def test_sendmail_with_ascii_body(self): + with self.mail.connect() as conn: + with mock.patch.object(conn, 'host') as host: + msg = Message(subject="testing", + sender="from@example.com", + recipients=["to@example.com"], + body="body") + conn.send(msg) + + host.sendmail.assert_called_once_with( + "from@example.com", + ["to@example.com"], + msg.as_bytes() if PY3 else msg.as_string(), + msg.mail_options, + msg.rcpt_options + ) + + def test_sendmail_with_non_ascii_body(self): + with self.mail.connect() as conn: + with mock.patch.object(conn, 'host') as host: + msg = Message(subject="testing", + sender="from@example.com", + recipients=["to@example.com"], + body=u"Öö") + + conn.send(msg) + + host.sendmail.assert_called_once_with( + "from@example.com", + ["to@example.com"], + msg.as_bytes() if PY3 else msg.as_string(), msg.mail_options, msg.rcpt_options )