Si vous utilisez Python 2.x, n'oubliez pas qu'il existe deux types de chaînes de caractères : str
y unicode
. str
sont des chaînes d'octets, tandis que unicode
sont des chaînes de caractères unicode. unicode
Les chaînes de caractères peuvent être utilisées pour représenter du texte dans n'importe quelle langue, mais pour stocker du texte dans un ordinateur ou l'envoyer par courrier électronique, vous devez représenter ce texte à l'aide d'octets. Pour représenter du texte à l'aide d'octets, vous avez besoin d'un format de codage. Il existe de nombreux formats de codage, Python utilise ascii par défaut, mais ascii ne peut représenter que quelques caractères, principalement des lettres anglaises. Si vous essayez de coder un texte avec d'autres lettres à l'aide de la fonction ascii vous obtiendrez le fameux "outside ordinal 128". Par exemple :
>>> u'Cerón'.encode('ascii')
Traceback (most recent call last):
File "<input>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 3:
ordinal not in range(128)
La même chose se produit si vous utilisez str(u'Cerón')
car Python utilise ascii par défaut pour convertir unicode
a str
.
Pour que cela fonctionne, vous devez utiliser un format de codage différent. UTF-8 est un format de codage qui permet d'exprimer tout texte unicode sous forme d'octets. Pour convertir le u'Cerón'
chaîne unicode en octets que vous devez utiliser :
>>> u'Cerón'.encode('utf-8')
'Cer\xc3\xb3n'
Aucune erreur cette fois-ci.
Maintenant, revenons à votre problème d'email. Je peux voir que vous utilisez MIMEText
qui accepte un code déjà encodé str
dans votre cas, c'est l'argument html
variable. MIMEText
accepte également un argument spécifiant le type d'encodage utilisé. Ainsi, dans votre cas, si html
est une chaîne unicode, vous devez la coder en tant que utf-8
et passer le paramètre charset aussi (parce que HTMLText
utilise ascii par défaut) :
part1 = MIMEText(html.encode('utf-8'), 'html', 'utf-8')
Mais faites attention, car si html
est déjà un str
au lieu de unicode
alors l'encodage échouera. C'est l'un des problèmes de Python 2.x, il vous permet d'encoder une chaîne déjà encodée mais il jette une erreur.
Un autre problème à ajouter à la liste est que utf-8 est compatible avec ascii et Python essaiera toujours d'encoder/décoder automatiquement les chaînes de caractères à l'aide de ascii . Si vous n'encodez pas correctement vos chaînes de caractères, mais que vous utilisez seulement ascii personnages, les choses fonctionneront bien. Toutefois, si pour une raison quelconque, certains non-ascii caractères se glisse dans votre message, vous obtiendrez l'erreur, ce qui rend les erreurs plus difficiles à détecter.