Python 3 smtplib send avec des caractères unicode
-
07-07-2019 - |
Question
Je ne parviens pas à envoyer des caractères unicode par e-mail à l'aide de smtplib en Python 3. Cela échoue en 3.1.1, mais fonctionne en 2.5.4:
import smtplib
from email.mime.text import MIMEText
sender = to = 'ABC@DEF.com'
server = 'smtp.DEF.com'
msg = MIMEText('€10')
msg['Subject'] = 'Hello'
msg['From'] = sender
msg['To'] = to
s = smtplib.SMTP(server)
s.sendmail(sender, [to], msg.as_string())
s.quit()
J'ai essayé un exemple tiré de la documentation, qui a également échoué. http://docs.python.org/3.1/library/email-examples. html , envoyez le contenu d’un répertoire sous forme d’exemple de message MIME
Des suggestions?
La solution
La clé est dans la documentation :
class email.mime.text.MIMEText(_text, _subtype='plain', _charset='us-ascii')
Une sous-classe de MIMENonMultipart, la La classe MIMEText est utilisée pour créer MIME objets de texte de type majeur. _text est la chaîne pour la charge utile. _sous-type est le type mineur et par défaut à plaine. _charset est le jeu de caractères du texte et est passé en tant que paramètre de MIMENonMultipart constructeur; il nous par défaut ascii. Aucune estimation ou encodage n'est effectué sur les données de texte.
Donc, ce dont vous avez besoin est clairement, pas msg = MIMEText ('€ 10')
, mais plutôt:
msg = MIMEText('€10'.encode('utf-8'), _charset='utf-8')
Bien que pas clairement documenté, sendmail nécessite une chaîne d'octets, pas une chaîne Unicode (c'est ce que le protocole SMTP spécifie); Regardez à quoi ressemble msg.as_string ()
pour chacune des deux manières de le construire - compte tenu du caractère "pas de recherche ni d'encodage", votre chemin a toujours ce caractère euro (et aucun pour que sendmail le transforme en bytestring), le mien ne le fait pas (et utf-8 est clairement spécifié).
Autres conseils
_charset
de MIMEText
est défini par défaut sur us-ascii
conformément au docs . Puisque €
ne vient pas de nous, il ne fonctionne pas.
exemple dans la documentation que vous avez essayé indique clairement:
Pour cet exemple, supposons que le fichier texte ne contienne que des caractères ASCII.
Vous pouvez utiliser . get_charset
sur votre message pour étudier le jeu de caractères, il existe également .set_charset
également.
Gus Mueller présentait un problème similaire: http://bugs.python.org/issue4403