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
Comments
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:
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. |
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? |
(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)? |
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? |
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?
|
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? |
|
I meant which types of *payload* should they accept. Here's an illustration of what I mean: http://paste.ubuntu.com/894731/. |
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. |
New changeset 1d5856849e64 by R David Murray in branch '3.3': New changeset 9046ef201591 by R David Murray in branch 'default': |
This should now be fixed. Calling MIMEApplication with a binary payload and passing it encode_quopri as the encoder will now actually work. |
New changeset 7c807bc15fa8 by R David Murray in branch '3.3': New changeset 36cc8b0446b3 by R David Murray in branch 'default': |
New changeset 64e004737837 by R David Murray in branch '3.3': |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: