email.policy: Объекты политики

Добавлено в версии 3.3.

Исходный код: Lib/email/policy.py.


Основным направлением пакета email является обработка сообщений электронной почты, как описано в различных RFC по электронной почте и MIME. Однако общий формат почтовых сообщений (блок полей заголовков, каждый из которых состоит из имени, за которым следует двоеточие, затем значение, за всем блоком следует пустая строка и произвольное «тело»), является форматом, который нашел применение за пределами сферы электронной почты. Некоторые из этих применений довольно точно соответствуют основным RFC электронной почты, некоторые - нет. Даже при работе с электронной почтой бывают случаи, когда желательно нарушить строгое соответствие RFC, например, для создания электронных писем, взаимодействующих с почтовыми серверами, которые сами не следуют стандартам, или для реализации расширений, которые вы хотите использовать в нарушение стандартов.

Объекты политики дают пакету электронной почты гибкость для обработки всех этих разрозненных сценариев использования.

Объект Policy заключает в себе набор атрибутов и методов, которые управляют поведением различных компонентов пакета email во время использования. Экземпляры Policy можно передавать различным классам и методам пакета email для изменения поведения по умолчанию. Ниже описаны настраиваемые значения и их значения по умолчанию.

Существует политика по умолчанию, используемая всеми классами в пакете email. Для всех классов parser и связанных с ними функций удобства, а также для класса Message это политика Compat32 через соответствующий предопределенный экземпляр compat32. Эта политика обеспечивает полную обратную совместимость (в некоторых случаях, включая совместимость с ошибками) с версией пакета email, существовавшей до Python3.3.

Это значение по умолчанию для ключевого слова policy в EmailMessage является политикой EmailPolicy через ее предварительно определенный экземпляр default.

Когда создается объект Message или EmailMessage, он приобретает политику. Если сообщение создается с помощью parser, то политика, переданная синтаксическому анализатору, будет политикой, используемой создаваемым им сообщением. Если сообщение создается программой, то политика может быть указана при его создании. Когда сообщение передается в generator, генератор по умолчанию использует политику из сообщения, но вы также можете передать генератору определенную политику, которая будет переопределять политику, хранящуюся в объекте сообщения.

Значение по умолчанию ключевого слова policy для классов email.parser и функций удобства парсера будет изменено в будущей версии Python. Поэтому вы должны всегда явно указывать, какую политику вы хотите использовать при вызове любого из классов и функций, описанных в модуле parser.

В первой части этой документации рассматриваются возможности Policy, abstract base class, который определяет функции, общие для всех объектов политики, включая compat32. Сюда входят определенные методы hook, вызываемые внутри пакета email, которые пользовательская политика может переопределить для получения другого поведения. Вторая часть описывает конкретные классы EmailPolicy и Compat32, которые реализуют хуки, обеспечивающие стандартное поведение и поведение и возможности обратной совместимости, соответственно.

Экземпляры Policy неизменяемы, но их можно клонировать, принимая те же аргументы ключевых слов, что и конструктор класса, и возвращая новый экземпляр Policy, который является копией оригинала, но с измененными значениями заданных атрибутов.

В качестве примера, следующий код может быть использован для чтения сообщения электронной почты из файла на диске и передачи его в системную программу sendmail в системе 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()

Здесь мы указываем BytesGenerator использовать символы разделителя строк, соответствующие RFC, при создании двоичной строки для передачи в sendmail's stdin, в то время как политика по умолчанию использует разделители строк \n.

Некоторые методы пакета электронной почты принимают аргумент policy, позволяющий переопределить политику для этого метода. Например, следующий код использует метод as_bytes() объекта msg из предыдущего примера и записывает сообщение в файл, используя родные разделители строк для платформы, на которой он запущен:

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

Объекты политики также могут быть объединены с помощью оператора сложения, создавая объект политики, настройки которого представляют собой комбинацию значений не по умолчанию суммируемых объектов:

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

Эта операция не является коммутативной; то есть порядок, в котором складываются объекты, имеет значение. Для примера:

>>> 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)

Это abstract base class для всех классов политик. Он предоставляет реализацию по умолчанию для пары тривиальных методов, а также реализацию свойства неизменяемости, метода clone() и семантики конструктора.

Конструктору класса политики могут быть переданы различные аргументы в виде ключевых слов. Аргументами, которые могут быть указаны, являются любые неметодные свойства данного класса, плюс любые дополнительные неметодные свойства конкретного класса. Значение, указанное в конструкторе, отменяет значение по умолчанию для соответствующего атрибута.

Этот класс определяет следующие свойства, и поэтому значения для них могут быть переданы в конструктор любого класса политики:

max_line_length

Максимальная длина любой строки в сериализованном выводе, не считая символа(ов) конца строки. По умолчанию 78, за RFC 5322. Значение 0 или None указывает на то, что обертывание строк вообще не должно выполняться.

linesep

Строка, которая будет использоваться для завершения строк в сериализованном выводе. По умолчанию используется \n, поскольку это внутренняя дисциплина конца строки, используемая Python, хотя \r\n требуется RFC.

cte_type

Управляет типом кодировок передачи содержимого, которые могут или должны использоваться. Возможными значениями являются:

7bit

все данные должны быть «7-битно чистыми» (только ASCII). Это означает, что при необходимости данные будут закодированы с использованием кодировки quoted-printable или base64.

8bit

данные не ограничены 7-битной чистотой. Данные в заголовках по-прежнему должны быть только ASCII и поэтому будут закодированы (см. fold_binary() и utf8 ниже для исключений), но части тела могут использовать 8bit CTE.

Значение cte_type 8bit работает только с BytesGenerator, но не с Generator, поскольку строки не могут содержать двоичные данные. Если Generator работает с политикой, определяющей cte_type=8bit, он будет действовать так, как будто cte_type является 7bit.

raise_on_defect

Если True, то все встреченные дефекты будут выдаваться как ошибки. Если False (по умолчанию), дефекты будут переданы в метод register_defect().

mangle_from_

Если True, то строки, начинающиеся с «From « в теле, экранируются путем размещения перед ними символа >. Этот параметр используется, когда сообщение сериализуется генератором. По умолчанию: False.

Добавлено в версии 3.5: Параметр mangle_from_.

message_factory

Функция-фабрика для создания нового пустого объекта сообщения. Используется парсером при построении сообщений. По умолчанию имеет значение None, в этом случае используется Message.

Добавлено в версии 3.6.

Следующий метод Policy предназначен для вызова кодом, использующим библиотеку электронной почты для создания экземпляров политики с пользовательскими настройками:

clone(**kw)

Возвращает новый экземпляр Policy, атрибуты которого имеют те же значения, что и текущий экземпляр, за исключением тех случаев, когда этим атрибутам присваиваются новые значения с помощью аргументов ключевых слов.

Остальные методы Policy вызываются кодом пакета электронной почты и не предназначены для вызова приложением, использующим пакет электронной почты. Пользовательская политика должна реализовать все эти методы.

handle_defect(obj, defect)

Обработка дефекта, найденного на obj. Когда пакет электронной почты вызывает этот метод, дефект всегда будет подклассом Defect.

Реализация по умолчанию проверяет флаг raise_on_defect. Если он равен True, то дефект поднимается как исключение. Если он равен False (по умолчанию), obj и defect передаются в register_defect().

register_defect(obj, defect)

Зарегистрируйте дефект на obj. В почтовом пакете дефект всегда будет подклассом Defect.

Реализация по умолчанию вызывает метод append атрибута defects в obj. Когда пакет email вызывает handle_defect, obj обычно имеет атрибут defects, который имеет метод append. Пользовательские типы объектов, используемые с почтовым пакетом (например, пользовательские объекты Message), также должны предоставлять такой атрибут, иначе дефекты в разобранных сообщениях будут вызывать непредвиденные ошибки.

header_max_count(name)

Возвращает максимально допустимое количество заголовков с именем name.

Вызывается при добавлении заголовка к объекту EmailMessage или Message. Если возвращаемое значение не является 0 или None, и уже существует количество заголовков с именем name больше или равно возвращаемому значению, то возникает ошибка ValueError.

Поскольку по умолчанию Message.__setitem__ добавляет значение к списку заголовков, легко создать дубликаты заголовков, не осознавая этого. Этот метод позволяет ограничить количество экземпляров некоторых заголовков, которые могут быть добавлены к Message программно. (Ограничение не соблюдается синтаксическим анализатором, который будет исправно создавать столько заголовков, сколько существует в разбираемом сообщении).

Реализация по умолчанию возвращает None для всех имен заголовков.

header_source_parse(sourcelines)

Пакет email вызывает этот метод со списком строк, каждая из которых заканчивается символами разделения строк, найденными в разбираемом источнике. Первая строка включает имя заголовка поля и разделитель. Все пробельные символы в источнике сохраняются. Метод должен вернуть кортеж (name, value), который будет храниться в Message для представления разобранного заголовка.

Если реализация хочет сохранить совместимость с существующими политиками почтовых пакетов, name должно быть именем с сохранением регистра (все символы до разделителя „:“), а value должно быть развернутым значением (все символы разделителя строк удалены, но пробельные символы сохранены), очищенным от ведущих пробельных символов.

sourcelines может содержать двоичные данные с суррогатной подписью.

Не существует реализации по умолчанию

header_store_parse(name, value)

Пакет электронной почты вызывает этот метод с именем и значением, предоставленными прикладной программой, когда прикладная программа изменяет Message программно (в отличие от Message, созданного синтаксическим анализатором). Метод должен возвращать кортеж (name, value), который будет храниться в Message для представления заголовка.

Если реализация хочет сохранить совместимость с существующими политиками почтовых пакетов, name и value должны быть строками или подклассами строк, которые не изменяют содержимое переданных аргументов.

Не существует реализации по умолчанию

header_fetch_parse(name, value)

Пакет электронной почты вызывает этот метод с именем и значением, хранящимися в данный момент в Message, когда этот заголовок запрашивается прикладной программой, и все, что возвращает метод, передается обратно приложению в качестве значения извлекаемого заголовка. Обратите внимание, что в Message может храниться более одного заголовка с одинаковым именем; методу передается конкретное имя и значение заголовка, который должен быть возвращен приложению.

значение может содержать двоичные данные с суррогатной подписью. В значении, возвращаемом методом, не должно быть двоичных данных с суррогатной подписью.

Не существует реализации по умолчанию

fold(name, value)

Пакет электронной почты вызывает этот метод с именем и значением, хранящимися в настоящее время в Message для данного заголовка. Метод должен вернуть строку, которая представляет этот заголовок, «свернутый» правильно (в соответствии с настройками политики) путем соединения name с value и вставки символов linesep в соответствующих местах. Обсуждение правил складывания заголовков электронной почты см. в RFC 5322.

значение может содержать двоичные данные с суррогатной подписью. В строке, возвращаемой методом, не должно быть двоичных данных с суррогатной подписью.

fold_binary(name, value)

То же самое, что и fold(), за исключением того, что возвращаемое значение должно быть не строкой, а байтовым объектом.

Значение может содержать двоичные данные с суррогатной подписью. Они могут быть преобразованы обратно в двоичные данные в возвращаемом объекте bytes.

class email.policy.EmailPolicy(**kw)

Этот конкретный Policy обеспечивает поведение, которое должно быть полностью совместимо с текущими RFC электронной почты. Они включают (но не ограничиваются ими) RFC 5322, RFC 2047 и текущие RFC MIME.

Эта политика добавляет новые алгоритмы разбора и сворачивания заголовков. Вместо простых строк заголовки представляют собой подклассы str с атрибутами, зависящими от типа поля. Алгоритм разбора и сворачивания полностью реализует RFC 2047 и RFC 5322.

Значением по умолчанию для атрибута message_factory является EmailMessage.

В дополнение к перечисленным выше настраиваемым атрибутам, которые применяются ко всем политикам, эта политика добавляет следующие дополнительные атрибуты:

Добавлено в версии 3.6: 1

utf8

Если False, следуйте RFC 5322, поддерживая в заголовках символы, не являющиеся символами ASCII, кодируя их как «кодированные слова». Если True, следуйте RFC 6532 и используйте кодировку utf-8 для заголовков. Сообщения, отформатированные таким образом, могут передаваться на SMTP-серверы, поддерживающие расширение SMTPUTF8 (RFC 6531).

refold_source

Если значение для заголовка в объекте Message было получено от parser (в отличие от того, что было установлено программой), этот атрибут указывает, должен ли генератор развернуть это значение при преобразовании сообщения обратно в сериализованную форму. Возможными значениями являются:

none

все исходные значения используют оригинальное складывание

long

исходные значения, у которых любая строка длиннее, чем max_line_length, будут перевернуты

all

все ценности складываются заново.

По умолчанию используется значение long.

header_factory

Вызываемая функция, которая принимает два аргумента, name и value, где name - имя поля заголовка, а value - развернутое значение поля заголовка, и возвращает строковый подкласс, представляющий этот заголовок. По умолчанию предоставляется header_factory (см. headerregistry), который поддерживает пользовательский разбор для различных типов полей заголовков адреса и даты RFC 5322, а также основных типов полей заголовков MIME. Поддержка дополнительного пользовательского разбора будет добавлена в будущем.

content_manager

Объект, имеющий по крайней мере два метода: get_content и set_content. Когда вызывается метод get_content() или set_content() объекта EmailMessage, он вызывает соответствующий метод этого объекта, передавая ему объект сообщения в качестве первого аргумента, и любые аргументы или ключевые слова, которые были переданы ему в качестве дополнительных аргументов. По умолчанию content_manager имеет значение raw_data_manager.

Добавлено в версии 3.4.

Класс предоставляет следующие конкретные реализации абстрактных методов Policy:

header_max_count(name)

Возвращает значение атрибута max_count специализированного класса, используемого для представления заголовка с заданным именем.

header_source_parse(sourcelines)

Имя разбирается как все до „:“ и возвращается в неизменном виде. Значение определяется путем удаления ведущих пробельных символов из оставшейся части первой строки, соединения всех последующих строк вместе и удаления любых символов возврата каретки или перевода строки.

header_store_parse(name, value)

Имя возвращается без изменений. Если входное значение имеет атрибут name и совпадает с name, игнорируя регистр, значение возвращается без изменений. В противном случае name и value передаются в header_factory, и в качестве значения возвращается результирующий объект заголовка. В этом случае возникает ошибка ValueError, если входное значение содержит символы CR или LF.

header_fetch_parse(name, value)

Если значение имеет атрибут name, оно возвращается немодифицированным. В противном случае имя и значение с удаленными символами CR или LF передаются в header_factory, и возвращается результирующий объект заголовка. Любые байты с суррогатной подписью превращаются в глиф неизвестного символа Юникода.

fold(name, value)

Складывание заголовков контролируется параметром политики refold_source. Значение считается «исходным значением» тогда и только тогда, когда оно не имеет атрибута name (наличие атрибута name означает, что это какой-то объект заголовка). Если исходное значение должно быть свернуто в соответствии с политикой, оно преобразуется в объект заголовка путем передачи name и value с удаленными символами CR и LF в header_factory. Складывание объекта заголовка выполняется вызовом его метода fold с текущей политикой.

Исходные значения разбиваются на строки с помощью splitlines(). Если значение не должно быть развернуто, строки соединяются с помощью linesep из политики и возвращаются. Исключением являются строки, содержащие двоичные данные неаскриптового алфавита. В этом случае значение складывается независимо от установки refold_source, что приводит к тому, что двоичные данные кодируются CTE с использованием набора символов unknown-8bit.

fold_binary(name, value)

То же самое, что и fold(), если cte_type равно 7bit, за исключением того, что возвращаемое значение - байт.

Если cte_type имеет значение 8bit, двоичные данные, не относящиеся к кодировке ASCII, преобразуются обратно в байты. Заголовки с двоичными данными не разворачиваются, независимо от установки refold_header, поскольку нет возможности узнать, состоят ли двоичные данные из однобайтовых или многобайтовых символов.

Следующие экземпляры EmailPolicy предоставляют значения по умолчанию, подходящие для конкретных областей применения. Обратите внимание, что в будущем поведение этих экземпляров (в частности, экземпляра HTTP) может быть скорректировано для более точного соответствия RFC, относящимся к их областям.

email.policy.default

Экземпляр EmailPolicy со всеми неизменными значениями по умолчанию. Эта политика использует стандартные окончания строк Python \n, а не RFC-корректные \r\n.

email.policy.SMTP

Подходит для сериализации сообщений в соответствии с почтовыми RFC. Как default, но с linesep, установленным на \r\n, что соответствует RFC.

email.policy.SMTPUTF8

То же самое, что и SMTP, за исключением того, что utf8 является True. Используется для сериализации сообщений в хранилище сообщений без использования кодированных слов в заголовках. Следует использовать только для передачи по протоколу SMTP, если адреса отправителя или получателя содержат символы, отличные от символов ASCII (метод smtplib.SMTP.send_message() обрабатывает это автоматически).

email.policy.HTTP

Подходит для сериализации заголовков с целью использования в HTTP-трафике. Как SMTP, за исключением того, что max_line_length устанавливается на None (неограниченно).

email.policy.strict

Удобный экземпляр. То же самое, что и default, за исключением того, что raise_on_defect устанавливается на True. Это позволяет сделать любую политику строгой, написав:

somepolicy + policy.strict

При всех этих EmailPolicies эффективный API почтового пакета изменяется по сравнению с API Python 3.2 следующим образом:

  • Установка заголовка на Message приводит к тому, что этот заголовок разбирается и создается объект заголовка.

  • Получение значения заголовка из Message приводит к разбору этого заголовка, созданию и возврату объекта заголовка.

  • Любой объект заголовка или любой заголовок, который повторно складывается из-за настроек политики, складывается с помощью алгоритма, который полностью реализует алгоритмы складывания RFC, включая знание того, где требуются и разрешены кодированные слова.

С точки зрения приложения это означает, что любой заголовок, полученный через EmailMessage, является объектом заголовка с дополнительными атрибутами, строковое значение которого является полностью декодированным значением заголовка в кодировке unicode. Аналогично, заголовку можно присвоить новое значение или создать новый заголовок, используя строку unicode, и политика позаботится о преобразовании строки unicode в правильную кодированную форму RFC.

Объекты заголовка и их атрибуты описаны в headerregistry.

class email.policy.Compat32(**kw)

Этот конкретный Policy является политикой обратной совместимости. Она повторяет поведение пакета email в Python 3.2. Модуль policy также определяет экземпляр этого класса, compat32, который используется в качестве политики по умолчанию. Таким образом, поведение пакета email по умолчанию направлено на поддержание совместимости с Python 3.2.

Следующие атрибуты имеют значения, отличные от значения по умолчанию Policy:

mangle_from_

По умолчанию используется значение True.

Класс предоставляет следующие конкретные реализации абстрактных методов Policy:

header_source_parse(sourcelines)

Имя разбирается как все до „:“ и возвращается в неизменном виде. Значение определяется путем удаления ведущих пробельных символов из оставшейся части первой строки, соединения всех последующих строк вместе и удаления любых символов возврата каретки или перевода строки.

header_store_parse(name, value)

Имя и значение возвращаются неизмененными.

header_fetch_parse(name, value)

Если значение содержит двоичные данные, оно преобразуется в объект Header с использованием кодовой таблицы unknown-8bit. В противном случае оно возвращается без изменений.

fold(name, value)

Заголовки сворачиваются с использованием алгоритма сворачивания Header, который сохраняет существующие переносы строк в значении, и заворачивает каждую полученную строку в max_line_length. Двоичные данные, не относящиеся к кодировке ASCII, кодируются CTE с использованием кодовой таблицы unknown-8bit.

fold_binary(name, value)

Заголовки сворачиваются с использованием алгоритма сворачивания Header, который сохраняет существующие переносы строк в значении, и заворачивает каждую полученную строку в max_line_length. Если cte_type равно 7bit, двоичные данные, не являющиесяascii, кодируются CTE с использованием кодовой таблицы unknown-8bit. В противном случае используется исходный заголовок источника, с существующими переносами строк и любыми (RFC недействительными) двоичными данными, которые он может содержать.

email.policy.compat32

Экземпляр Compat32, обеспечивающий обратную совместимость с поведением пакета email в Python 3.2.

Сноски

1

Первоначально был добавлен в 3.3 как provisional feature.

Вернуться на верх