email.policy: Policy Objects

Ajouté dans la version 3.3.

Code source : Lib/email/policy.py


Le principal objectif du paquet email est la gestion des messages électroniques comme décrit par les diverses RFC de messagerie et MIME. Cependant, le format général des messages électroniques (un bloc de champs d'en-tête composés chacun d'un nom suivi de deux-points suivi d'une valeur, le bloc entier suivi d'une ligne vide et d'un « corps » arbitraire), est un format qui a trouvé son utilité en dehors du domaine du courrier électronique. Certaines de ces utilisations sont assez conformes aux principales RFC de messagerie, d'autres non. Même lorsque vous travaillez avec des e-mails, il est parfois souhaitable de ne pas respecter strictement les RFC, par exemple en générant des e-mails qui interagissent avec des serveurs de messagerie qui ne respectent pas eux-mêmes les normes ou qui implémentent des extensions que vous souhaitez utiliser d'une manière qui enfreint les normes.

Les objets de définition de politique donnent au paquet de messagerie la flexibilité nécessaire pour gérer tous ces cas d'utilisation disparates.

Un objet Policy encapsule un ensemble d'attributs et de méthodes qui contrôlent le comportement de divers composants du paquet de messagerie lors de son utilisation. Les instances Policy peuvent être transmises à diverses classes et méthodes dans le paquet de courrier électronique pour modifier le comportement par défaut. Les valeurs réglables et leurs valeurs par défaut sont décrites ci-dessous.

Il existe une politique par défaut utilisée par toutes les classes dans le paquet de messagerie. Pour toutes les classes parser et les fonctions pratiques associées, et pour la classe Message, il s'agit de la politique Compat32, via son instance correspondante prédéfinie compat32. Cette politique fournit une rétrocompatibilité complète (dans certains cas, y compris la compatibilité des bogues) avec la version pré-Python3.3 du paquet de messagerie.

Cette valeur par défaut pour le paramètre nommé policy de EmailMessage est la politique EmailPolicy, via son instance prédéfinie default.

Lorsqu'un objet Message ou EmailMessage est créé, il acquiert une politique. Si le message est créé par un parser, la politique transmise à l'analyseur est la politique utilisée par le message qu'il crée. Si le message est créé par le programme, la stratégie peut être spécifiée lors de sa création. Lorsqu'un message est passé à un generator, le générateur utilise la politique du message par défaut, mais vous pouvez également passer une politique spécifique au générateur qui remplace celle stockée sur l'objet message.

La valeur par défaut du paramètre nommé policy pour les classes email.parser et les fonctions pratiques de l'analyseur va changer dans une future version de Python. Par conséquent, vous devez toujours spécifier explicitement la stratégie que vous souhaitez utiliser lors de l'appel de l'une des classes et fonctions décrites dans le module parser.

La première partie de cette documentation couvre les fonctionnalités de Policy, une classe mère abstraite qui définit les fonctionnalités communes à tous les objets de stratégie, y compris compat32. Cela inclut certaines méthodes automatiques (hooks en anglais) appelées en interne par le paquet de messagerie, qu'une stratégie personnalisée peut remplacer pour obtenir un comportement différent. La deuxième partie décrit les classes concrètes EmailPolicy et Compat32, qui implémentent les points d'entrée automatiques qui fournissent respectivement le comportement standard et le comportement et les fonctionnalités rétrocompatibles.

Les instances Policy sont immuables, mais elles peuvent être clonées, en acceptant les mêmes arguments nommés que le constructeur de classe et en renvoyant une nouvelle instance Policy qui est une copie de l'original mais avec les valeurs d'attributs spécifiées modifiées.

Par exemple, le code suivant peut être utilisé pour lire un message électronique à partir d'un fichier sur le disque et le transmettre au programme système sendmail sur un système Unix :

>>> from email import message_from_binary_file
>>> from email.generator import BytesGenerator
>>> from email import policy
>>> from subprocess import Popen, PIPE
>>> with open('mymsg.txt', 'rb') as f:
...     msg = message_from_binary_file(f, policy=policy.default)
...
>>> p = Popen(['sendmail', msg['To'].addresses[0]], stdin=PIPE)
>>> g = BytesGenerator(p.stdin, policy=msg.policy.clone(linesep='\r\n'))
>>> g.flatten(msg)
>>> p.stdin.close()
>>> rc = p.wait()

Ici, nous disons à BytesGenerator d'utiliser les caractères de séparation de ligne corrects de la RFC lors de la création de la chaîne binaire à fournir à stdin de sendmail, où la politique par défaut utiliserait \n comme séparateur de ligne.

Certaines méthodes du paquet de messagerie acceptent un argument nommé policy, permettant à la politique d'être remplacée pour cette méthode. Par exemple, le code suivant utilise la méthode as_bytes() de l'objet msg de l'exemple précédent et écrit le message dans un fichier en utilisant les séparateurs de ligne natifs de la plate-forme sur laquelle il est en cours d'exécution :

>>> import os
>>> with open('converted.txt', 'wb') as f:
...     f.write(msg.as_bytes(policy=msg.policy.clone(linesep=os.linesep)))
17

Les objets de stratégie peuvent également être combinés à l'aide de l'opérateur d'addition, produisant un objet de stratégie dont les paramètres sont une combinaison des objets additionnées (en ne prenant en compte que les paramètres données explicitement) :

>>> compat_SMTP = policy.compat32.clone(linesep='\r\n')
>>> compat_strict = policy.compat32.clone(raise_on_defect=True)
>>> compat_strict_SMTP = compat_SMTP + compat_strict

Cette opération n'est pas commutative ; c'est-à-dire que l'ordre dans lequel les objets sont ajoutés est important. Pour illustrer :

>>> policy100 = policy.compat32.clone(max_line_length=100)
>>> policy80 = policy.compat32.clone(max_line_length=80)
>>> apolicy = policy100 + policy80
>>> apolicy.max_line_length
80
>>> apolicy = policy80 + policy100
>>> apolicy.max_line_length
100
class email.policy.Policy(**kw)

C'est la classe mère abstraite pour toutes les classes de définition de politique. Elle fournit des implémentations par défaut pour quelques méthodes triviales, ainsi que l'implémentation de la propriété d'immutabilité, la méthode clone() et la sémantique du constructeur.

Le constructeur d'une classe de définition de politique peut recevoir divers arguments nommés. Les arguments qui peuvent être spécifiés sont toutes les propriétés qui ne sont pas des méthodes sur cette classe, plus toutes les propriétés qui ne sont pas des méthodes supplémentaires sur la classe concrète. Une valeur spécifiée dans le constructeur remplace la valeur par défaut de l'attribut correspondant.

Cette classe définit les propriétés suivantes, et ainsi les valeurs des éléments suivants peuvent être passées dans le constructeur de n'importe quelle classe de définition de politique :

max_line_length

La longueur maximale de toute ligne dans la sortie sérialisée, sans compter le(s) caractère(s) de fin de ligne. La valeur par défaut est 78, selon la RFC 5322. Une valeur de 0 ou None indique qu'aucun retour à la ligne ne doit être fait.

linesep

La chaîne à utiliser pour terminer les lignes dans la sortie sérialisée. La valeur par défaut est \n car c'est la définition interne de fin de ligne utilisée par Python, bien que \r\n soit requis par les RFC.

cte_type

Contrôle le type d'encodage de contenu qui peut ou doit être utilisé. Les valeurs possibles sont :

7bit

toutes les données doivent être « complétement 7 bits » (ASCII uniquement). Cela signifie que si nécessaire, les données seront encodées à l'aide de l'encodage quoted-printable ou base64.

8bit

les données ne sont pas contraintes d'être uniquement sur 7 bits. Les données dans les en-têtes doivent toujours être en ASCII uniquement et seront donc encodées (voir fold_binary() et utf8 ci-dessous pour les exceptions), mais les parties du corps peuvent utiliser le 8bit CTE.

Une valeur cte_type de 8bit ne fonctionne qu'avec BytesGenerator, et pas avec Generator car les chaînes ne peuvent pas contenir de données binaires. Si un Generator fonctionne sous une politique qui spécifie cte_type=8bit, il agit comme si cte_type était 7bit.

raise_on_defect

Si True, tous les défauts rencontrés sont signalés comme des erreurs. Si False (la valeur par défaut), les défauts sont passés à la méthode register_defect().

mangle_from_

Si True, les lignes commençant par "From " dans le corps sont échappées en mettant un > devant elles. Ce paramètre est utilisé lorsque le message est sérialisé par un générateur. Par défaut, vaut False.

Ajouté dans la version 3.5.

message_factory

Une fonction de fabrique pour construire un nouvel objet de message vide. Utilisé par l'analyseur lors de la construction des messages. La valeur par défaut est None, Message est alors utilisé.

Ajouté dans la version 3.6.

verify_generated_headers

If True (the default), the generator will raise HeaderWriteError instead of writing a header that is improperly folded or delimited, such that it would be parsed as multiple headers or joined with adjacent data. Such headers can be generated by custom header classes or bugs in the email module.

As it's a security feature, this defaults to True even in the Compat32 policy. For backwards compatible, but unsafe, behavior, it must be set to False explicitly.

Ajouté dans la version 3.13.

La méthode Policy suivante est destinée à être appelée par le code à l'aide de la bibliothèque de messagerie pour créer des instances de stratégie avec des paramètres personnalisés :

clone(**kw)

Renvoie une nouvelle instance de Policy dont les attributs ont les mêmes valeurs que l'instance actuelle, sauf si ces attributs reçoivent de nouvelles valeurs par les arguments nommés.

Les méthodes Policy restantes sont appelées par le code du paquet de messagerie et ne sont pas destinées à être appelées par une application utilisant le paquet de messagerie. Une stratégie personnalisée doit implémenter toutes ces méthodes.

handle_defect(obj, defect)

Gère un defect trouvé sur obj. Lorsque le paquet de messagerie appelle cette méthode, defect est toujours une sous-classe de Defect.

L'implémentation par défaut vérifie le drapeau raise_on_defect. Si c'est True, defect est levé comme une exception. Si c'est False (par défaut), obj et defect sont passés à register_defect().

register_defect(obj, defect)

Enregistre un defect sur obj. Dans le paquet de messagerie, defect sera toujours une sous-classe de Defect.

L'implémentation par défaut appelle la méthode append de l'attribut defects de obj. Lorsque le paquet de courrier électronique appelle handle_defect, obj a normalement un attribut defects qui a une méthode append. Les types d'objets personnalisés utilisés avec le paquet de messagerie (par exemple, les objets Message personnalisés) doivent également fournir un tel attribut, sinon les défauts dans les messages analysés généreront des erreurs inattendues.

header_max_count(name)

Renvoie le nombre maximal autorisé d'en-têtes nommés name.

Appelé lorsqu'un en-tête est ajouté à un objet EmailMessage ou Message. Si la valeur renvoyée n'est pas 0 ou None, et qu'il y a déjà un certain nombre d'en-têtes avec le nom name supérieur ou égal à la valeur renvoyée, une ValueError est levée.

Parce que le comportement par défaut de Message.__setitem__ est d'ajouter la valeur à la liste des en-têtes, il est facile de créer des en-têtes en double sans s'en rendre compte. Cette méthode permet à certains en-têtes d'être limités dans le nombre d'instances de cet en-tête qui peuvent être ajoutées à un Message par programme (la limite n'est pas respectée par l'analyseur, qui produit fidèlement autant d'en-têtes qu'il en existe dans le message analysé).

L'implémentation par défaut renvoie None pour tous les noms d'en-tête.

header_source_parse(sourcelines)

Le paquet de courrier électronique appelle cette méthode avec une liste de chaînes, chaque chaîne se terminant par les caractères de séparation de ligne trouvés dans la source analysée. La première ligne comprend le nom de l'en-tête de champ et le séparateur. Tous les espaces blancs dans la source sont préservés. La méthode doit renvoyer le couple (name, value) qui doit être stocké dans le Message pour représenter l'en-tête analysé.

Si une implémentation souhaite conserver la compatibilité avec les politiques de paquet de messagerie existantes, name doit être le nom préservé de la casse (tous les caractères jusqu'au séparateur :), tandis que value doit être la valeur dépliée (c.-à-d. tous les caractères de séparation de ligne supprimés, mais les espaces blancs conservés intacts), dépouillés des espaces blancs de tête.

sourcelines peut contenir des données binaires échappées de substitution.

Il n'y a pas d'implémentation par défaut

header_store_parse(name, value)

Le paquet de courrier électronique appelle cette méthode avec le nom et la valeur fournis par le programme d'application lorsque le programme d'application modifie un Message par programme (par opposition à un Message créé par un analyseur). La méthode doit renvoyer le couple (name, value) qui doit être stocké dans le Message pour représenter l'en-tête.

Si une implémentation souhaite conserver la compatibilité avec les politiques existantes du paquet de messagerie, le name et la value doivent être des chaînes ou des sous-classes de chaînes qui ne modifient pas le contenu des arguments transmis.

Il n'y a pas d'implémentation par défaut

header_fetch_parse(name, value)

Le paquet de courrier électronique appelle cette méthode avec le name et la value actuellement stockés dans le Message lorsque cet en-tête est demandé par le programme d'application, et tout ce que la méthode renvoie est ce qui est renvoyé à l'application comme valeur de l'en-tête récupéré. Notez qu'il peut y avoir plus d'un en-tête avec le même nom stocké dans le Message ; la méthode reçoit le nom et la valeur spécifiques de l'en-tête destiné à être renvoyé à l'application.

value peut contenir des données binaires de substitution échappées. Il ne doit pas y avoir de données binaires échappées de substitution dans la valeur renvoyée par la méthode.

Il n'y a pas d'implémentation par défaut

fold(name, value)

Le paquet de courrier électronique appelle cette méthode avec le name et la value actuellement stockés dans le Message pour un en-tête donné. La méthode doit renvoyer une chaîne qui représente correctement cet en-tête « plié » (selon les paramètres de la politique) en mettant en forme le couple name - value et en insérant les caractères linesep aux endroits appropriés. Voir RFC 5322 pour une discussion sur les règles de mise en forme (« pliage » ou folding en anglais) des en-têtes de courrier électronique.

value peut contenir des données binaires de substitution échappées. Il ne doit pas y avoir de données binaires échappées de substitution dans la chaîne renvoyée par la méthode.

fold_binary(name, value)

Identique à fold(), sauf que la valeur renvoyée doit être un objet bytes plutôt qu'une chaîne.

value peut contenir des données binaires de substitution échappées. Celles-ci pourraient être reconverties en données binaires dans l'objet bytes renvoyé.

class email.policy.EmailPolicy(**kw)

Cette Policy concrète fournit un comportement destiné à être entièrement conforme aux RFC de messagerie actuelles. Ce qui inclut (mais n'est pas limité à) la RFC 5322, la RFC 2047 et les RFC MIME actuelles.

Cette politique ajoute de nouveaux algorithmes d'analyse d'en-tête et de mise en forme (« pliage »). Au lieu de simples chaînes, les en-têtes sont des sous-classes str avec des attributs qui dépendent du type du champ. L'algorithme d'analyse et de pliage implémente entièrement la RFC 2047 et la RFC 5322.

La valeur par défaut de l'attribut message_factory est EmailMessage.

Outre les attributs définissables répertoriés ci-dessus qui s'appliquent à toutes les règles, cette règle ajoute les attributs supplémentaires suivants :

Ajouté dans la version 3.6: [1]

utf8

Si c'est False, suit la RFC 5322, en prenant en charge les caractères non-ASCII dans les en-têtes en les encodant comme des « mots encodés ». Si c'est True, suit la RFC 6532 et utilise l'encodage utf-8 pour les en-têtes. Les messages formatés de cette manière peuvent être transmis aux serveurs SMTP qui gèrent l'extension SMTPUTF8 (RFC 6531).

refold_source

Si la valeur d'un en-tête dans l'objet Message provient d'un parser (au lieu d'être définie par un programme), cet attribut indique si un générateur doit ou non remettre en forme cette valeur lorsqu'il retransforme le message sous forme sérialisée. Les valeurs possibles sont :

none

toutes les valeurs sources utilisent la mise en forme (folding en anglais) d'origine

long

les valeurs sources dont une ligne est plus longue que max_line_length sont remises en forme

all

toutes les valeurs sont remises en forme.

La valeur par défaut est long.

header_factory

Appelable qui prend deux arguments, name et value, où name est un nom de champ d'en-tête et value est une valeur de champ d'en-tête dépliée (c-à-d. sans retours à la ligne de mise en forme), et renvoie une sous-classe de chaîne qui représente cet en-tête. Un header_factory par défaut (voir headerregistry) est fourni qui prend en charge l'analyse personnalisée pour les divers types de champs d'en-tête d'adresse et de date RFC 5322, et les principaux types de champs d'en-tête MIME. La prise en charge d'une analyse personnalisée supplémentaire sera ajoutée à l'avenir.

content_manager

Objet avec au moins deux méthodes : get_content et set_content. Lorsque la méthode get_content() ou set_content() d'un objet EmailMessage est appelée, elle appelle la méthode correspondante de cet objet, en lui transmettant l'objet message comme premier argument, et tous les arguments positionnels ou nommés qui lui ont été transmis comme arguments supplémentaires. Par défaut, content_manager est défini sur raw_data_manager.

Ajouté dans la version 3.4.

La classe fournit les implémentations concrètes suivantes des méthodes abstraites de Policy :

header_max_count(name)

Renvoie la valeur de l'attribut max_count de la classe spécialisée utilisée pour représenter l'en-tête avec le nom donné.

header_source_parse(sourcelines)

Le nom est analysé comme le reste jusqu'au : et renvoyé sans modification. La valeur est déterminée en supprimant les espaces blancs de début du reste de la première ligne, en joignant toutes les lignes suivantes et en supprimant tous les caractères de retour chariot ou de saut de ligne de fin.

header_store_parse(name, value)

Le nom est renvoyé tel quel. Si la valeur d'entrée a un attribut name et qu'elle correspond à name sans tenir compte de la casse, la valeur est renvoyée inchangée. Sinon, le name et la value sont passés à header_factory, et l'objet d'en-tête résultant est renvoyé comme valeur. Dans ce cas, une ValueError est levée si la valeur d'entrée contient des caractères CR ou LF.

header_fetch_parse(name, value)

Si la valeur a un attribut name, elle est renvoyée sans modification. Sinon, le name et la value sans les caractères CR ou LF sont passés à header_factory, et l'objet d'en-tête résultant est renvoyé. Tous les octets échappés de substitution sont transformés en glyphe Unicode de caractère inconnu.

fold(name, value)

La mise en forme d'en-tête est contrôlée par le paramètre de politique refold_source. Une valeur est considérée comme une « valeur source » si et seulement si elle n'a pas d'attribut name (avoir un attribut name signifie qu'il s'agit d'un objet d'en-tête quelconque). Si une valeur source doit être mise en forme conformément à la politique, elle est convertie en un objet d'en-tête en passant le name et la value avec tous les caractères CR et LF supprimés à header_factory. La mise en forme multi-lignes d'un objet d'en-tête (« pliage » ou folding en anglais) se fait en appelant sa méthode fold avec la politique actuelle.

Les valeurs sources sont divisées en lignes en utilisant splitlines(). Si la valeur ne doit pas être remise en forme, les lignes sont jointes en utilisant le caractère linesep de la politique et renvoyées. L'exception concerne les lignes contenant des données binaires non ASCII. Dans ce cas, la valeur est remise en forme quel que soit le paramètre refold_source, ce qui entraîne le codage CTE des données binaires à l'aide du jeu de caractères unknown-8bit.

fold_binary(name, value)

Identique à fold() si cte_type vaut 7bit, sauf que la valeur renvoyée est de type bytes.

Si cte_type est 8bit, les données binaires non-ASCII sont reconverties en octets. Les en-têtes contenant des données binaires ne sont pas remises en forme, quel que soit le paramètre refold_header, puisqu'il n'y a aucun moyen de savoir si les données binaires sont constituées de caractères à un seul octet ou de caractères à plusieurs octets.

Les instances suivantes de EmailPolicy fournissent des valeurs par défaut adaptées à des domaines d'application spécifiques. Notez qu'à l'avenir, le comportement de ces instances (en particulier l'instance HTTP) pourra être ajusté pour se conformer encore plus étroitement aux RFC relatives à leurs domaines.

email.policy.default

Une instance de EmailPolicy avec toutes les valeurs par défaut inchangées. Cette politique utilise les fins de ligne standard Python \n plutôt que le \r\n conforme à la RFC.

email.policy.SMTP

Convient pour la sérialisation des messages conformément aux RFC des e-mails. Comme default, mais avec linesep défini sur \r\n, ce qui est conforme à la RFC.

email.policy.SMTPUTF8

Identique à SMTP sauf que utf8 vaut True. Utile pour sérialiser des messages dans une banque de messages sans utiliser de mots encodés dans les en-têtes. Ne doit être utilisée pour la transmission SMTP que si les adresses de l'expéditeur ou du destinataire contiennent des caractères non ASCII (la méthode smtplib.SMTP.send_message() gère cela automatiquement).

email.policy.HTTP

Convient pour la sérialisation des en-têtes à utiliser dans le trafic HTTP. Comme SMTP sauf que max_line_length est défini sur None (illimité).

email.policy.strict

Exemple de commodité. Identique à default sauf que raise_on_defect est défini sur True. Cela permet de rendre stricte toute politique en écrivant :

somepolicy + policy.strict

Avec toutes ces EmailPolicies, l'API effective du paquet de messagerie est modifiée par rapport à l'API Python 3.2 de la manière suivante :

  • Définir un en-tête sur un Message entraîne l'analyse de cet en-tête et la création d'un objet d'en-tête.

  • La récupération d'une valeur d'en-tête à partir d'un Message entraîne l'analyse de cet en-tête ainsi que la création et le renvoi d'un objet d'en-tête.

  • Tout objet d'en-tête, ou tout en-tête qui est remis en forme en raison des paramètres de politique, est mis en forme à l'aide d'un algorithme qui implémente entièrement les algorithmes de pliage de la RFC, notamment en sachant où les mots encodés sont requis et autorisés.

Du point de vue de l'application, cela signifie que tout en-tête obtenu via EmailMessage est un objet d'en-tête avec des attributs supplémentaires, dont la valeur de chaîne est la valeur Unicode entièrement décodée de l'en-tête. De même, un en-tête peut se voir attribuer une nouvelle valeur, ou un nouvel en-tête créé, à l'aide d'une chaîne Unicode, et la politique se chargera de convertir la chaîne Unicode dans la forme encodée RFC correcte.

Les objets d'en-tête et leurs attributs sont décrits dans headerregistry.

class email.policy.Compat32(**kw)

Cette Policy concrète est la politique de rétrocompatibilité. Elle reproduit le comportement du paquet de courrier électronique dans Python 3.2. Le module policy définit également une instance de cette classe, compat32, qui est utilisée comme politique par défaut. Ainsi, le comportement par défaut du paquet de messagerie est de maintenir la compatibilité avec Python 3.2.

Les attributs suivants ont des valeurs différentes de la valeur par défaut de Policy :

mangle_from_

La valeur par défaut est True.

La classe fournit les implémentations concrètes suivantes des méthodes abstraites de Policy :

header_source_parse(sourcelines)

Le nom est analysé comme le reste jusqu'au : et renvoyé sans modification. La valeur est déterminée en supprimant les espaces blancs de début du reste de la première ligne, en joignant toutes les lignes suivantes et en supprimant tous les caractères de retour chariot ou de saut de ligne de fin.

header_store_parse(name, value)

Le nom et la valeur sont renvoyés sans modification.

header_fetch_parse(name, value)

Si la valeur contient des données binaires, elle est convertie en un objet Header en utilisant le jeu de caractères unknown-8bit. Sinon, elle est renvoyée sans modification.

fold(name, value)

Les en-têtes sont mis en forme à l'aide de l'algorithme de pliage Header, qui préserve les sauts de ligne existants dans la valeur et encapsule chaque ligne résultante dans la max_line_length. Les données binaires non-ASCII sont codées en CTE à l'aide du jeu de caractères unknown-8bit.

fold_binary(name, value)

Les en-têtes sont mis en forme à l'aide de l'algorithme de pliage Header, qui préserve les sauts de ligne existants dans la valeur et encapsule chaque ligne résultante dans la max_line_length. Si cte_type est 7bit, les données binaires non-ASCII sont encodées en CTE en utilisant le jeu de caractères unknown-8bit. Sinon, l'en-tête source d'origine est utilisé, avec ses sauts de ligne existants et toutes les données binaires (non conformes à la RFC) qu'il peut contenir.

email.policy.compat32

Instance de Compat32, offrant une rétrocompatibilité avec le comportement du paquet de messagerie dans Python 3.2.

Notes