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

Added in version 3.3.

Источник: Lib/email/policy.py


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

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

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

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

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

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

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

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

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

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

Added in version 3.5.

message_factory

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

Added in version 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. Когда почтовый пакет вызывает 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 должно быть развернутым значением (все символы-разделители строк удалены, но пробельные символы сохранены), очищенным от ведущих пробельных символов.

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

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

header_store_parse(name, value)

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

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

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

header_fetch_parse(name, value)

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

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

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

fold(name, value)

Почтовый пакет вызывает этот метод с именем и значением, хранящимися в Message для данного заголовка. Метод должен вернуть строку, которая представляет этот заголовок, «свернутый» правильно (в соответствии с настройками политики) путем соединения имени со значением и вставки символов 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.

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

Added in version 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.

Added in version 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, то двоичные данные, не содержащие асиев, кодируются CTE с использованием гарнитуры unknown-8bit. В противном случае используется исходный заголовок источника с существующими разрывами строк и любыми (RFC недействительными) двоичными данными, которые он может содержать.

email.policy.compat32

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

Сноски