python: sending a mail, fails when inside a “with” block

可紊 提交于 2021-01-28 04:45:55

问题


I am wondering why this code

test = smtplib.SMTP('smtp.gmail.com', 587)
test.ehlo()
test.starttls()
test.ehlo()
test.login('address','passw')
test.sendmail(sender, recipients, composed)
test.close()

works, but when written like this

with smtplib.SMTP('smtp.gmail.com', 587) as s:
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login('address','passw')
    s.sendmail(sender, recipients, composed)
    s.close()

it fails with the message

Unable to send the email. Error:  <class 'AttributeError'>
Traceback (most recent call last):
  File "py_script.py", line 100, in <module>
    with smtplib.SMTP('smtp.gmail.com', 587) as s:
AttributeError: __exit__

Why is this happening? (python3 on a raspberry pi) Thx


回答1:


You are not using Python 3.3 or up. In your version of Python, smtplib.SMTP() is not a context manager and cannot be using in a with statement.

The traceback is directly caused because there is no __exit__ method, a requirement for context managers.

From the smptlib.SMTP() documentation:

Changed in version 3.3: Support for the with statement was added.

You can wrap the object in a context manager with @contextlib.contextmanager:

from contextlib import contextmanager
from smtplib import SMTPResponseException, SMTPServerDisconnected

@contextmanager
def quitting_smtp_cm(smtp):
    try:
        yield smtp
    finally:
        try:
            code, message = smtp.docmd("QUIT")
            if code != 221:
                raise SMTPResponseException(code, message)
        except SMTPServerDisconnected:
            pass
        finally:
            smtp.close()

This uses the same exit behaviour as was added in Python 3.3. Use it like this:

with quitting_smtp_cm(smtplib.SMTP('smtp.gmail.com', 587)) as s:
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login('address','passw')
    s.sendmail(sender, recipients, composed)

Note that it'll close the connection for you.



来源:https://stackoverflow.com/questions/27882100/python-sending-a-mail-fails-when-inside-a-with-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!