19.1.4. email.policy: объекты Policy ¶email.policy: Policy Objects
Новое в версии 3.3.
Пакет email в первую очередь предназначен для обработки сообщений электронной почты в соответствии с различными RFC, описывающими формат email и MIME. Однако общий формат email-сообщений – блок заголовков, каждый из которых состоит из имени и следующего за ним двоеточия и значения, затем пустая строка и произвольное «тело» – нашёл применение и за пределами электронной почты. Некоторые из этих применений достаточно строго следуют основным RFC, другие – нет. И даже при работе с электронной почтой иногда возникает необходимость отойти от строгого соблюдения RFC.
Объекты Policy обеспечивают пакету email гибкость для обработки всех этих разнородных сценариев использования.
Объект Policy инкапсулирует набор атрибутов и методов, управляющих поведением различных компонентов пакета email во время использования. Экземпляры Policy можно передавать различным классам и методам пакета email, чтобы изменить поведение по умолчанию. Устанавливаемые значения и их значения по умолчанию описаны ниже.
Все классы пакета email используют политику по умолчанию. Эта политика называется Compat32 с соответствующим предопределённым экземпляром compat32. Она обеспечивает полную обратную совместимость (в некоторых случаях включая совместимость с ошибками) с версией пакета email, предшествующей Python 3.3.
Первая часть этой документации описывает возможности Policy – абстрактного базового класса, определяющего общие для всех объектов политики возможности, включая compat32. Сюда входят некоторые методы-хуки, внутренне вызываемые пакетом email; пользовательская политика может переопределить их для получения иного поведения.
При создании объекта Message он получает политику. По умолчанию это будет compat32, но можно указать другую политику. Если Message создаётся парсером, то переданная парсеру политика станет политикой создаваемого им Message. Если Message создаётся программой, то политику можно указать при его создании. Когда Message передаётся генератору, генератор по умолчанию использует политику из Message, но можно также передать генератору конкретную политику, которая переопределит сохранённую в объекте Message.
Экземпляры 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 при создании двоичной строки для передачи в stdin программы sendmail, тогда как политика по умолчанию использовала бы разделители строк \n.
Объекты Policy также можно комбинировать с помощью оператора сложения, получая объект политики, настройки которого представляют собой комбинацию нестандартных значений суммируемых объектов:
>>> 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)¶
Это абстрактный базовый класс для всех классов политик. Он предоставляет реализации по умолчанию для пары тривиальных методов, а также реализацию свойства неизменяемости, метода 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 и поэтому будут кодироваться (см. исключение «binary_fold» ниже), но части тела могут использовать CTE 8bit. Значение cte_type равное 8bit работает только с BytesGenerator, а не с Generator, поскольку строки не могут содержать двоичные данные. Если Generator работает в рамках политики, указывающей cte_type=8bit, он будет вести себя так, как если бы cte_type было 7bit.
- raise_on_defect¶
Если True, любые обнаруженные дефекты будут вызываться как ошибки. Если False (по умолчанию), дефекты передаются методу register_defect().
Следующий метод Policy предназначен для вызова кодом, использующим библиотеку email, для создания экземпляров политик с произвольными настройками:
- clone(**kw)¶
Возвращает новый экземпляр Policy, атрибуты которого имеют те же значения, что и у текущего экземпляра, за исключением тех атрибутов, которым присвоены новые значения через именованные аргументы.
Остальные методы Policy вызываются кодом пакета email и не предназначены для вызова приложением, использующим этот пакет. Пользовательская политика должна реализовывать все эти методы.
- handle_defect(obj, defect)¶
Обрабатывает дефект, обнаруженный на obj. Когда пакет email вызывает этот метод, defect всегда будет подклассом Defect.
Реализация по умолчанию проверяет флаг raise_on_defect. Если он равен True, defect возбуждается как исключение. Если он равен False (по умолчанию), obj и defect передаются register_defect().
- register_defect(obj, defect)¶
Регистрирует дефект на obj. В пакете email дефект всегда является подклассом Defect.
Реализация по умолчанию вызывает метод append атрибута defects объекта obj. Когда пакет email вызывает handle_defect, obj обычно имеет атрибут defects с методом append method. Пользовательские типы объектов, используемые с пакетом email (например, пользовательские объекты Message), также должны предоставлять такой атрибут, иначе дефекты в разобранных сообщениях вызовут неожиданные ошибки.
- header_max_count(name)¶
Возвращает максимально допустимое количество заголовков с именем name.
Вызывается, когда заголовок добавляется к Message объекту. Если возвращаемое значение не равно 0 или None, и уже имеется количество заголовков с именем name, равное возвращённому значению, возбуждается ValueError.
Поскольку поведение по умолчанию Message.__setitem__ заключается в добавлении значения к списку заголовков, можно случайно создать дублирующиеся заголовки, не осознавая этого. Этот метод позволяет программно ограничить количество экземпляров некоторых заголовков, которые могут быть добавлены в Message. (Парсер это ограничение не соблюдает; он добросовестно создаст столько заголовков, сколько есть в разбираемом сообщении.)
Реализация по умолчанию возвращает None для всех имён заголовков.
- header_source_parse(sourcelines)¶
Пакет email вызывает этот метод со списком строк, каждая строка заканчивается символами разделителя строк, найденными в разбираемом исходном тексте. Первая строка включает имя поля заголовка и разделитель. Все пробельные символы в исходнике сохраняются. Метод должен вернуть кортеж (name, value), который будет сохранён в Message для представления разобранного заголовка.
Если реализация хочет сохранить совместимость с существующими политиками пакета email, name должен быть именем с сохранённым регистром (все символы до разделителя ‘:‘), а value должно быть развёрнутым значением (все символы разделителя строк удалены, но пробельные символы сохранены), с удалёнными ведущими пробелами.
sourcelines может содержать двоичные данные, экранированные суррогатами.
Реализация по умолчанию отсутствует
- header_store_parse(name, value)¶
Пакет email вызывает этот метод с именем и значением, предоставленными прикладной программой, когда она программно изменяет объект Message (в отличие от Message, созданного парсером). Метод должен вернуть кортеж (name, value), который будет сохранён в Message для представления заголовка.
Если реализация хочет сохранить совместимость с существующими политиками пакета email, name и value должны быть строками или подклассами строк, которые не изменяют содержимое переданных аргументов.
Реализация по умолчанию отсутствует
- header_fetch_parse(name, value)¶
Пакет email вызывает этот метод с name и value, в данный момент сохранёнными в Message, когда прикладная программа запрашивает этот заголовок; что бы метод ни вернул, это и передаётся прикладной программе в качестве значения запрашиваемого заголовка. Обратите внимание, что в Message может храниться более одного заголовка с одним и тем же именем; методу передаются конкретные имя и значение заголовка, который должен быть возвращён приложению.
value может содержать бинарные данные с суррогатным экранированием. В возвращаемом методом значении не должно быть таких бинарных данных.
Реализация по умолчанию отсутствует
- fold(name, value)¶
Пакет email вызывает этот метод с name и value, в данный момент сохранёнными в Message для данного заголовка. Метод должен вернуть строку, представляющую этот заголовок, правильно «свёрнутым» (в соответствии с настройками политики), объединяя name с value и вставляя символы linesep в соответствующих местах. См. RFC 5322 для обсуждения правил сворачивания заголовков email.
value может содержать бинарные данные с суррогатным экранированием. В возвращаемой методом строке не должно быть таких бинарных данных.
- class email.policy.Compat32(**kw)¶
Этот конкретный Policy является политикой обратной совместимости. Он воспроизводит поведение пакета email в Python 3.2. Модуль policy также определяет экземпляр этого класса, compat32, который используется в качестве политики по умолчанию. Таким образом, поведение пакета email по умолчанию заключается в сохранении совместимости с Python 3.2.
Класс предоставляет следующие конкретные реализации абстрактных методов Policy:
- header_source_parse(sourcelines)¶
Имя разбирается как всё до символа ‘:‘ и возвращается без изменений. Значение определяется путём удаления ведущих пробелов из оставшейся части первой строки, объединения всех последующих строк вместе и удаления всех завершающих символов возврата каретки или перевода строки.
- header_store_parse(name, value)¶
Имя и значение возвращаются без изменений.
- header_fetch_parse(name, value)¶
Если значение содержит двоичные данные, оно преобразуется в объект Header с использованием charset unknown-8bit. В противном случае оно возвращается без изменений.
- fold(name, value)¶
Заголовки сворачиваются с использованием алгоритма сворачивания Header, который сохраняет существующие разрывы строк в значении и оборачивает каждую результирующую строку до max_line_length. Не-ASCII двоичные данные кодируются CTE с использованием charset unknown-8bit.
- fold_binary(name, value)¶
Заголовки сворачиваются с использованием алгоритма сворачивания Header, который сохраняет существующие разрывы строк в значении и оборачивает каждую результирующую строку до max_line_length. Если cte_type равен 7bit, не-ASCII двоичные данные кодируются CTE с использованием charset unknown-8bit. В противном случае используется исходный заголовок, с его существующими разрывами строк и любыми (не соответствующими RFC) двоичными данными, которые он может содержать.
Примечание
The documentation below describes new policies that are included in the standard library on a provisional basis. Backwards incompatible changes (up to and including removal of the feature) may occur if deemed necessary by the core developers.
- class email.policy.EmailPolicy(**kw)¶
Этот конкретный Policy обеспечивает поведение, предназначенное для полного соответствия текущим RFC email. К ним относятся (но не ограничиваясь) RFC 5322, RFC 2047 и текущие MIME RFC.
Эта политика добавляет новые алгоритмы разбора и свёртывания заголовков. Вместо простых строк заголовки представляют собой пользовательские объекты с пользовательскими атрибутами, зависящими от типа поля. Алгоритмы разбора и свёртывания полностью реализуют RFC 2047 и RFC 5322.
В дополнение к настраиваемым атрибутам, перечисленным выше и относящимся ко всем политикам, эта политика добавляет следующие дополнительные атрибуты:
- refold_source¶
If the value for a header in the Message object originated from a parser (as opposed to being set by a program), this attribute indicates whether or not a generator should refold that value when transforming the message back into stream form. The possible values are:
none все исходные значения используют исходное сворачивание long исходные значения, содержащие строки длиннее max_line_length, будут переформированы все все значения сворачиваются заново. По умолчанию long.
- header_factory¶
Вызываемый объект, который принимает два аргумента, name и value, где name – это имя поля заголовка, а value – развёрнутое значение поля заголовка, и возвращает подкласс строки, представляющий этот заголовок. Предоставляется стандартная header_factory (см. headerregistry), которая понимает некоторые типы полей заголовков RFC 5322. (В настоящее время поля адресов и дат обрабатываются особым образом, а все остальные поля считаются неструктурированными. Этот список будет дополнен до того, как расширение будет помечено как стабильное.)
Класс предоставляет следующие конкретные реализации абстрактных методов Policy:
- header_max_count(name)¶
Возвращает значение атрибута max_count специализированного класса, используемого для представления заголовка с заданным именем.
- header_store_parse(name, value)¶
Имя возвращается без изменений. Если входное значение имеет атрибут name, и он совпадает с name без учёта регистра, значение возвращается без изменений. В противном случае name и value передаются в header_factory, и полученный пользовательский объект заголовка возвращается в качестве значения. В этом случае возбуждается ValueError, если входное значение содержит символы CR или LF.
- header_fetch_parse(name, value)¶
Если значение имеет атрибут name, оно возвращается без изменений. В противном случае name и value с удалёнными символами CR или LF передаются в header_factory, и возвращается полученный пользовательский объект заголовка. Любые байты с суррогатным экранированием преобразуются в глиф неизвестного символа Unicode.
- fold(name, value)¶
Свёртывание заголовков управляется настройкой политики refold_source. Значение считается «исходным значением» тогда и только тогда, когда оно не имеет атрибута name (наличие атрибута name означает, что это некоторый объект заголовка). Если исходное значение необходимо заново свернуть в соответствии с политикой, оно преобразуется в пользовательский объект заголовка путём передачи name и value с удалёнными символами CR и LF в header_factory. Свёртывание пользовательского объекта заголовка выполняется вызовом его метода fold с текущей политикой.
Исходные значения разбиваются на строки с помощью splitlines(). Если значение не нужно переформировывать, строки объединяются обратно с использованием linesep из политики и возвращаются. Исключение составляют строки, содержащие не-ASCII двоичные данные. В этом случае значение переформировывается независимо от настройки 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¶
Подходит для сериализации сообщений в соответствии с email RFC. Как и default, но с linesep, установленным в \r\n, что соответствует RFC.
- email.policy.HTTP¶
Подходит для сериализации заголовков для использования в HTTP-трафике. Как и SMTP, за исключением того, что max_line_length установлено в None (без ограничений).
- email.policy.strict¶
Удобный экземпляр. То же, что и default, за исключением того, что raise_on_defect установлено в True. Это позволяет сделать любую политику строгой, написав:
somepolicy + policy.strict
Со всеми этими EmailPolicies эффективный API пакета email изменяется по сравнению с API Python 3.2 следующим образом:
- Установка заголовка в Message приводит к его разбору и созданию пользовательского объекта заголовка.
- Получение значения заголовка из Message приводит к его разбору и созданию и возврату пользовательского объекта заголовка.
- Любой пользовательский объект заголовка или заголовок, который повторно свёртывается из-за настроек политики, сворачивается с использованием алгоритма, полностью реализующего алгоритмы свёртывания RFC, включая знание того, где требуются и разрешены закодированные слова.
С точки зрения приложения это означает, что любой заголовок, полученный через Message, является пользовательским объектом заголовка с пользовательскими атрибутами, строковое значение которого – полностью декодированное значение заголовка в Unicode. Точно так же заголовку может быть присвоено новое значение, или создан новый заголовок с использованием строки Unicode, и политика позаботится о преобразовании строки Unicode в правильную закодированную форму RFC.
Пользовательские объекты заголовков и их атрибуты описаны в headerregistry.