python / cpython

The Python programming language
https://www.python.org
Other
63.35k stars 30.34k forks source link

smtplib.SMTP.sendmail: improve exception message #64681

Open cd65c590-98e9-41d1-9e7a-7754bceafdd7 opened 10 years ago

cd65c590-98e9-41d1-9e7a-7754bceafdd7 commented 10 years ago
BPO 20482
Nosy @warsaw, @ncoghlan, @bitdancer, @berkerpeksag

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: ```python assignee = None closed_at = None created_at = labels = ['type-feature', 'expert-email'] title = 'smtplib.SMTP.sendmail: improve exception message' updated_at = user = 'https://bugs.python.org/yegle' ``` bugs.python.org fields: ```python activity = actor = 'BreamoreBoy' assignee = 'none' closed = False closed_date = None closer = None components = ['email'] creation = creator = 'yegle' dependencies = [] files = [] hgrepos = [] issue_num = 20482 keywords = [] message_count = 4.0 messages = ['209943', '236411', '236412', '236464'] nosy_count = 5.0 nosy_names = ['barry', 'ncoghlan', 'r.david.murray', 'berker.peksag', 'yegle'] pr_nums = [] priority = 'normal' resolution = None stage = None status = 'open' superseder = None type = 'enhancement' url = 'https://bugs.python.org/issue20482' versions = ['Python 3.5'] ```

cd65c590-98e9-41d1-9e7a-7754bceafdd7 commented 10 years ago

Currently the msg argument of smtplib.SMTP.sendmail accept a str in Py3k if every characters in this str is in ASCII range, or a bytes.

This is confusing for new comer because:

  1. When you send your mail using only ASCII characters, everything is fine (no matter you use bytes or str).
  2. When sometimes you included non-ASCII characters in your email, the traceback is hard to understand.

Here's an example of such traceback:

Traceback (most recent call last):
  File "./manage.py", line 113, in <module>
    manager.run()
  File "/data/web/cgi-bin/venv/lib/python3.3/site-packages/flask_script/__init__.py", line 405, in run
    result = self.handle(sys.argv[0], sys.argv[1:])
  File "/data/web/cgi-bin/venv/lib/python3.3/site-packages/flask_script/__init__.py", line 384, in handle
    return handle(app, *positional_args, **kwargs)
  File "/data/web/cgi-bin/venv/lib/python3.3/site-packages/flask_script/commands.py", line 145, in handle
    return self.run(*args, **kwargs)
  File "./manage.py", line 108, in run
    conn.send(msg)
  File "/data/web/cgi-bin/venv/lib/python3.3/site-packages/flask_mail.py", line 168, in send
    message.as_string())
  File "/data/web/cgi-bin/python-3.3.3/lib/python3.3/smtplib.py", line 747, in sendmail
    msg = _fix_eols(msg).encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\u9f99' in position 646: ordinal not in range(128)

Here's my proposal:

--- smtplib.py.orig     2014-02-01 21:26:47.000000000 -0500
+++ smtplib.py  2014-02-01 21:37:51.000000000 -0500
@@ -744,7 +744,12 @@
         esmtp_opts = []
         print(msg)
         if isinstance(msg, str):
-            msg = _fix_eols(msg).encode('ascii')
+            try:
+                msg = _fix_eols(msg).encode('ascii')
+            except UnicodeEncodeError:
+                raise SMTPException(
+                    "msg may be a string containing characters in the "
+                    "ASCII range, or a byte string.")
         if self.does_esmtp:
             # Hmmm? what's this? -ddm
             # self.esmtp_features['7bit']=""
83d2e70e-e599-4a04-b820-3814bbdb9bef commented 9 years ago

Assuming that the inline patch in msg209943 is acceptable I'll volunteer to change the test code unless the originator wants the job.

cd65c590-98e9-41d1-9e7a-7754bceafdd7 commented 9 years ago

I have no plan to work further, Mark can take the code and improve anyway you want.

83d2e70e-e599-4a04-b820-3814bbdb9bef commented 9 years ago

I don't believe that there is much sense in implementing the proposed change. If the stdlib was changed every time a UnicodeEncodeError was reported just to show a slightly clearer exception message, I dread to think how much extra code would be added in total. Committing a change such as this takes core dev time which IMHO opinion could be put to better use.