Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

email.encoders.encode_quopri doesn't work with python 3.2 #58568

Closed
mitya57 mannequin opened this issue Mar 18, 2012 · 13 comments
Closed

email.encoders.encode_quopri doesn't work with python 3.2 #58568

mitya57 mannequin opened this issue Mar 18, 2012 · 13 comments
Assignees
Labels
topic-email type-bug An unexpected behavior, bug, or error

Comments

@mitya57
Copy link
Mannequin

mitya57 mannequin commented Mar 18, 2012

BPO 14360
Nosy @warsaw, @bitdancer, @mitya57

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/bitdancer'
closed_at = <Date 2013-06-27.22:41:15.669>
created_at = <Date 2012-03-18.09:36:34.575>
labels = ['type-bug', 'expert-email']
title = "email.encoders.encode_quopri doesn't work with python 3.2"
updated_at = <Date 2013-08-22.01:14:27.683>
user = 'https://github.com/mitya57'

bugs.python.org fields:

activity = <Date 2013-08-22.01:14:27.683>
actor = 'python-dev'
assignee = 'r.david.murray'
closed = True
closed_date = <Date 2013-06-27.22:41:15.669>
closer = 'r.david.murray'
components = ['email']
creation = <Date 2012-03-18.09:36:34.575>
creator = 'mitya57'
dependencies = []
files = []
hgrepos = []
issue_num = 14360
keywords = []
message_count = 13.0
messages = ['156238', '156298', '156493', '156494', '156498', '156499', '156542', '156544', '156549', '191964', '191965', '192011', '195848']
nosy_count = 4.0
nosy_names = ['barry', 'r.david.murray', 'python-dev', 'mitya57']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue14360'
versions = ['Python 3.3', 'Python 3.4']

@mitya57
Copy link
Mannequin Author

mitya57 mannequin commented Mar 18, 2012

Currently my /usr/lib/python3.2/email/encoders.py has this code:

def _qencode(s):
    enc = _encodestring(s, quotetabs=True)
    # Must encode spaces, which quopri.encodestring() doesn't do
    return enc.replace(' ', '=20')

The problem is that _encodestring (which is just quopri.encodestring) always returns bytes, trying to run replace() on bytes raises "TypeError: expected an object with the buffer interface".

This leads to email.encoders.encode_quopri never working.

So, I think this should be changed to something like this:

<...>
return enc.decode().replace(' ', '=20')

Example log:

Python 3.2.3rc1 (default, Mar  9 2012, 23:02:43) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import email.encoders
>>> from email.mime.text import MIMEText
>>> msg = MIMEText(b'some text here')
>>> email.encoders.encode_quopri(msg)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.2/email/encoders.py", line 44, in encode_quopri
    encdata = _qencode(orig)
  File "/usr/lib/python3.2/email/encoders.py", line 23, in _qencode
    return enc.replace(' ', '=20')
TypeError: expected an object with the buffer interface

Reproduced on Ubuntu precise with Python 3.2.3rc1. Replacing encode_quopri with encode_base64 works fine.

@mitya57 mitya57 mannequin added type-crash A hard crash of the interpreter, possibly with a core dump stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error and removed type-crash A hard crash of the interpreter, possibly with a core dump labels Mar 18, 2012
@bitdancer
Copy link
Member

Interesting. Apparently we have no tests for the encode_ functions, nor do we use them inside the email package itself (except for encode_7or8bit).

Do you have any interest in writing a patch with tests?

@bitdancer bitdancer self-assigned this Mar 19, 2012
@mitya57
Copy link
Mannequin Author

mitya57 mannequin commented Mar 21, 2012

(Sorry for not replying earlier).

I think the main priority here is getting things working, not the tests (so I have little interest in that).

First of all, should quopri.encodestring() really return bytes? Everything it returns is ascii text, obviously.

Then, which types of argument should encode_* functions take (I think str should be supported, and it's not a case here as encode_quopri will only accept bytes)?

@bitdancer
Copy link
Member

Well, a patch won't get committed if it lacks tests, so commit would have to wait until I have time to write some, then.

The encode_ methods (from email.encoders) take *message* objects as their arguments. MIMEText internally converts a byte string into the appropriate CTE *if* you give it a charset (if you don't it later produces an error, but that's a different bug). So if you pass bytes you don't need to call an encode_ method separately.

In fact, there's really no reason to call an encode_ method at all, since if you pass a string to MIMEText when giving it a non-ascii unicode string, it will default to utf-8 and do the appropriate CTE encoding.

But given that they exist in the documented API and exist in Python2, they need to be fixed to work in an equivalent fashion in Python3. I think the only case where they would do anything useful is if you don't like Python's default for the CTE encoding and want to change it. (Note that you can accomplish that globally by updating the charset alias in the charset module.)

What is your use case, by the way?

@mitya57
Copy link
Mannequin Author

mitya57 mannequin commented Mar 21, 2012

In fact, there's really no reason to call an encode_ method at all, since if you pass a string to MIMEText when giving it a non-ascii unicode string, it will default to utf-8 and do the appropriate CTE encoding.

No, it doesn't:
Python 3.2.3rc1 (default, Mar  9 2012, 23:02:43) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from email.mime.text import MIMEText
>>> print(MIMEText('йцукен'))
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

йцукен

>>

As you can see, it leaves russian text in unmodified state and sets the charset to "us-ascii". Should it be considered as a bug?

What is your use case, by the way?
I'm writing a "send via e-mail" plugin for my ReText editor (http://retext.sourceforge.net/).

@bitdancer
Copy link
Member

Oh, you are right. I even noted that bug in my PyCon talk, but immediately forgot about it :( I do intend to fix it.

You can get it to work by explicitly passing the charset:

  >>> x = MIMEText('йцукен', _charset='utf8')
  >>> str(x)
'Content-Type: text/plain; charset="utf8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: base64\n\n0LnRhtGD0LrQtdC9\n'

When I asked the use case, I meant specifically for calling encode_quopri, etc. Given the above, do you need it anymore?

@mitya57
Copy link
Mannequin Author

mitya57 mannequin commented Mar 22, 2012

You can get it to work by explicitly passing the charset
Thanks, I didn't know about that.

Given the above, do you need it anymore?
No.

@mitya57
Copy link
Mannequin Author

mitya57 mannequin commented Mar 22, 2012

Then, which types of argument should encode_* functions take (I think str should be supported, and it's not a case here as encode_quopri will only accept bytes)?

I meant which types of *payload* should they accept. Here's an illustration of what I mean: http://paste.ubuntu.com/894731/.

@bitdancer
Copy link
Member

email in python3 doesn't necessarily work with binary payloads. (Obviously here you've found the opposite problem, but it is in methods that aren't used by the package itself.) There aren't any tests of binary payloads in the test suite. Ultimately this needs to be fixed one way or another, but I'm not sure when it is going to happen.

@bitdancer bitdancer added topic-email and removed stdlib Python modules in the Lib dir labels May 28, 2012
@python-dev
Copy link
Mannequin

python-dev mannequin commented Jun 27, 2013

New changeset 1d5856849e64 by R David Murray in branch '3.3':
bpo-14360: make encoders.encode_quopri work.
http://hg.python.org/cpython/rev/1d5856849e64

New changeset 9046ef201591 by R David Murray in branch 'default':
Merge bpo-14360: make encoders.encode_quopri work.
http://hg.python.org/cpython/rev/9046ef201591

@bitdancer
Copy link
Member

This should now be fixed. Calling MIMEApplication with a binary payload and passing it encode_quopri as the encoder will now actually work.

@python-dev
Copy link
Mannequin

python-dev mannequin commented Jun 28, 2013

New changeset 7c807bc15fa8 by R David Murray in branch '3.3':
bpo-14360: Add news item.
http://hg.python.org/cpython/rev/7c807bc15fa8

New changeset 36cc8b0446b3 by R David Murray in branch 'default':
Merge bpo-14360: Add news item.
http://hg.python.org/cpython/rev/36cc8b0446b3

@python-dev
Copy link
Mannequin

python-dev mannequin commented Aug 22, 2013

New changeset 64e004737837 by R David Murray in branch '3.3':
bpo-18324: set_payload now correctly handles binary input.
http://hg.python.org/cpython/rev/64e004737837

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-email type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant