#32806: Send email with a content_type=text/* attachment
---------------------------------+--------------------------------------
     Reporter:  tzot             |                    Owner:  nobody
         Type:  Uncategorized    |                   Status:  new
    Component:  Core (Mail)      |                  Version:  3.2
     Severity:  Normal           |               Resolution:
     Keywords:  text attachment  |             Triage Stage:  Unreviewed
    Has patch:  0                |      Needs documentation:  0
  Needs tests:  0                |  Patch needs improvement:  0
Easy pickings:  0                |                    UI/UX:  0
---------------------------------+--------------------------------------
Description changed by tzot:

Old description:

> Python 3.8, Django 3.2.3
> {{{
> from django.core.mail import EmailMessage
>
> e = EmailMessage('subject', 'the body', '[email protected]',
> ['[email protected]'])
> e.attach('attachment.csv', 'flda,fldb\nvala,valb\n', 'text/csv')
> e.send()
> }}}
> This fails as expected:
> {{{
> …
>   File "…/lib/python3.8/site-packages/sgbackend/mail.py", line 149, in
> _build_sg_mail
>     base64_attachment = base64.b64encode(attachment[1])
>   File "…/lib/python3.8/base64.py", line 58, in b64encode
>     encoded = binascii.b2a_base64(s, newline=False)
> }}}
>
> But this also fails:
> {{{
> e.attach('attachment.csv', b'flda,fldb\nvala,valb\n', 'text/csv')
> e.send()
> }}}
>
> because …/lib/python3.8/site-packages/django/core/mail/message.py on
> attach does:
>
> {{{
>             if basetype == 'text':
>                 if isinstance(content, bytes):
>                     try:
>                         content = content.decode()
>                     except UnicodeDecodeError:
>                         # If mimetype suggests the file is text but it's
>                         # actually binary, read() raises a
> UnicodeDecodeError.
>                         mimetype = DEFAULT_ATTACHMENT_MIME_TYPE
>
>             self.attachments.append((filename, content, mimetype))
> }}}
>
> Why decode it if a Py3 string can't be b64encoded?  I think that actually
> it should be *encoded* as bytes if already str using the DEFAULT_CHARSET
> before appending the tuple to self.attachments.
>
> If I .attach(name, bytes_object, 'application/csv') then the send
> operation works fine.
>
> (I'm open to the possibility that I miss something and this is not a bug
> :) )
>
> I can provide a patch if we decide upon the correct behaviour, but please
> let me know the target branch.

New description:

 Python 3.8.5, Django 3.2.3
 {{{
 from django.core.mail import EmailMessage

 e = EmailMessage('subject', 'the body', '[email protected]',
 ['[email protected]'])
 e.attach('attachment.csv', 'flda,fldb\nvala,valb\n', 'text/csv')
 e.send()
 }}}
 This fails as expected:
 {{{
 …
   File "…/lib/python3.8/site-packages/sgbackend/mail.py", line 149, in
 _build_sg_mail
     base64_attachment = base64.b64encode(attachment[1])
   File "…/lib/python3.8/base64.py", line 58, in b64encode
     encoded = binascii.b2a_base64(s, newline=False)
 }}}

 But this also fails:
 {{{
 e.attach('attachment.csv', b'flda,fldb\nvala,valb\n', 'text/csv')
 e.send()
 }}}

 because `…/lib/python3.8/site-packages/django/core/mail/message.py` on
 `attach` does:

 {{{
             if basetype == 'text':
                 if isinstance(content, bytes):
                     try:
                         content = content.decode()
                     except UnicodeDecodeError:
                         # If mimetype suggests the file is text but it's
                         # actually binary, read() raises a
 UnicodeDecodeError.
                         mimetype = DEFAULT_ATTACHMENT_MIME_TYPE

             self.attachments.append((filename, content, mimetype))
 }}}

 Why decode it if a Py3 string can't be b64encoded?  I think that actually
 it should be *encoded* as bytes if already str using the DEFAULT_CHARSET
 before appending the tuple to self.attachments.

 If I `.attach(name, bytes_object, 'application/csv')` then the send
 operation works fine.

 (I'm open to the possibility that I miss something and this is not a bug
 :) )

 I can provide a patch if we decide upon the correct behaviour, but please
 let me know the target branch.

--

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

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/062.37dc8399f815794947ec62207cdbe4bf%40djangoproject.com.

Reply via email to