[Django] #24623: AttributeError when trying to send an utf-8 encoded email with text attachments (mime type: text/*)

56 views
Skip to first unread message

Django

unread,
Apr 10, 2015, 11:54:37 AM4/10/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------+-------------------------------------------------
Reporter: tkrapp | Owner: nobody
Type: Bug | Status: new
Component: Core | Version: 1.7
(Mail) | Keywords: email python3 SafeMIMEText MIMEText
Severity: Normal | attach_file
Triage Stage: | Has patch: 0
Unreviewed |
Easy pickings: 0 | UI/UX: 0
-------------------------+-------------------------------------------------
I get "AttributeError: 'bytes' object has no attribute 'encode'" when
trying to send a utf-8 encoded email with text attachments (see stack
trace below).

As far as I can see this happens when using python 3 (like we do) and
utf-8 as encoding.
* If you attach a text/csv file for example, django tries to instantiate a
SafeMIMEText object with the following parameters: (text: bytes(...),
subtype: 'csv', charset: 'utf-8') (django/core/mail/message.py:338)
* SafeMIMEText calls init of MIMEText and sets the charset to None
explicitly when charset was 'utf-8' before but does not convert text from
bytes to str which is expected by MIMEText
(django/core/mail/message.py:175)
* MIMEText then tries to encode the provided _text parameter as 'us-ascii'
and fails since a bytes object has no encode-method in python3
(email/mime/text.py:33)

'''Example'''
{{{
from django.core.mail import EmailMessage

email = EmailMessage('subject', 'body', 'fr...@example.com',
['t...@example.com'])
email.attach_file('/path/to/csv.file')

email.send()
}}}

Solutions I could think of:
* Convert text parameter of SafeMIMEText from bytes to str before calling
init of MIMEText. This would imply that one knows the encoding of the text
file or the file encoding is detected automatically.
* Convert the file content and call attach of EmailMessage.

'''Stack trace''':
{{{
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/__init__.py", line 385, in
execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File
"/mnt/storage/django/code/trouble_ticket/management/commands/send2ntt.py",
line 41, in handle
raise(e)
File
"/mnt/storage/django/code/trouble_ticket/management/commands/send2ntt.py",
line 39, in handle
email.send()
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/message.py", line 286, in send
return self.get_connection(fail_silently).send_messages([self])
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/backends/smtp.py", line 99, in send_messages
sent = self._send(message)
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/backends/smtp.py", line 113, in _send
message = email_message.message()
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/message.py", line 253, in message
msg = self._create_message(msg)
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/message.py", line 312, in _create_message
return self._create_attachments(msg)
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/message.py", line 325, in _create_attachments
msg.attach(self._create_attachment(*attachment))
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/message.py", line 367, in _create_attachment
attachment = self._create_mime_attachment(content, mimetype)
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/message.py", line 338, in
_create_mime_attachment
attachment = SafeMIMEText(content, subtype, encoding)
File "/usr/local/lib/python3.4/dist-
packages/django/core/mail/message.py", line 175, in __init__
MIMEText.__init__(self, text, subtype, None)
File "/usr/lib/python3.4/email/mime/text.py", line 33, in __init__
_text.encode('us-ascii')
AttributeError: 'bytes' object has no attribute 'encode'
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24623>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 11, 2015, 10:08:29 AM4/11/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------

Reporter: tkrapp | Owner: nobody
Type: Bug | Status: new
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: => 0
* needs_docs: => 0
* needs_tests: => 0
* stage: Unreviewed => Accepted


Comment:

Reproduced with the attached test (`EmailMessage.attach_file()` is
untested at the moment).

--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:1>

Django

unread,
Apr 11, 2015, 10:08:38 AM4/11/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------

Reporter: tkrapp | Owner: nobody
Type: Bug | Status: new
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* Attachment "24623-test.diff" added.

Django

unread,
Apr 15, 2015, 3:32:11 AM4/15/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner:
| ChillarAnand
Type: Bug | Status: assigned

Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ChillarAnand):

* owner: nobody => ChillarAnand
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:2>

Django

unread,
Apr 16, 2015, 10:32:29 AM4/16/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner:
Type: Bug | Status: new

Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ChillarAnand):

* owner: ChillarAnand =>
* status: assigned => new


--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:3>

Django

unread,
Jul 17, 2015, 8:04:25 AM7/17/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner:
Type: Bug | Status: new

Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by kswiat):

* Attachment "24623_workaround_1.diff" added.

Django

unread,
Jul 17, 2015, 8:05:43 AM7/17/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned

Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by kswiat):

* status: new => assigned
* owner: => kswiat


Comment:

https://docs.python.org/3/library/functions.html#open
Files opened in binary mode (including 'b' in the mode argument) return
contents as bytes objects without any decoding.

`EmailMessage.attach_file()` opens a attachment file with 'rb' mode. which
results in a `bytes` object content. In case of a `text` base mimetype,
content is beeing sent to python's `MimeText`, and then `encode()` fails
on `bytes` object.

I attached a simple workaround patch.

--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:4>

Django

unread,
Jul 17, 2015, 10:38:15 AM7/17/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by claudep):

Would you mind creating a pull request with your patch, including the test
from Tim?

--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:5>

Django

unread,
Jul 17, 2015, 11:06:44 AM7/17/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by kswiat):

Of course, I will create PR within a few hours.

--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:6>

Django

unread,
Jul 17, 2015, 4:25:44 PM7/17/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by kswiat):

* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:7>

Django

unread,
Jul 18, 2015, 11:29:28 AM7/18/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Ready for
SafeMIMEText MIMEText attach_file | checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by claudep):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:8>

Django

unread,
Jul 21, 2015, 6:48:03 AM7/21/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1
* stage: Ready for checkin => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:9>

Django

unread,
Jul 23, 2015, 1:54:14 PM7/23/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by kswiat):

PR updated.

--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:10>

Django

unread,
Jul 24, 2015, 10:24:55 AM7/24/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by kswiat):

* needs_better_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:11>

Django

unread,
Jul 25, 2015, 4:01:45 AM7/25/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: assigned
Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution:
Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by phalt):

@kswiat - you've got some tests in there already, are there any more
edgecases that you can think of? It doesn't hurt to have more.

--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:12>

Django

unread,
Jul 25, 2015, 7:44:04 AM7/25/15
to django-...@googlegroups.com
#24623: AttributeError when trying to send an utf-8 encoded email with text
attachments (mime type: text/*)
-------------------------------------+-------------------------------------
Reporter: tkrapp | Owner: kswiat
Type: Bug | Status: closed

Component: Core (Mail) | Version: 1.7
Severity: Normal | Resolution: fixed

Keywords: email python3 | Triage Stage: Accepted
SafeMIMEText MIMEText attach_file |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"c6da621def9bc04a5feacd5652c7f9d84f48ad2c" c6da621]:
{{{
#!CommitTicketReference repository=""
revision="c6da621def9bc04a5feacd5652c7f9d84f48ad2c"
Fixed #24623 -- Fixed EmailMessage.attach_file() with text files on Python
3.

Thanks tkrapp for the report and Tim Graham for the review.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24623#comment:13>

Reply all
Reply to author
Forward
0 new messages