Документация Python неофициальный перевод

19.1.4. email.policy: объекты Policyemail.policy: Policy Objects

Новое в версии 3.3.

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


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

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

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

Во всех классах пакета email используется политика по умолчанию. Эта политика называется Compat32, и ей соответствует предопределённый экземпляр compat32. Она обеспечивает полную обратную совместимость (в некоторых случаях включая совместимость с ошибками) с версией пакета email до Python 3.3.

The first part of this documentation covers the features of Policy, an abstract base class that defines the features that are common to all policy objects, including compat32. This includes certain hook methods that are called internally by the email package, which a custom policy could override to obtain different behavior.

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

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

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

Некоторые методы пакета email принимают ключевой аргумент 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

Объекты 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().

mangle_from_

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

Новое в версии 3.5: Параметр mangle_from_.

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

clone(**kw)

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

Остальные методы Policy вызываются кодом пакета email и не предназначены для вызова из приложения, использующего пакет 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 всегда будет подклассом Defect.

Реализация по умолчанию вызывает метод append атрибута defects объекта obj. Когда пакет email вызывает handle_defect, объект obj обычно имеет атрибут defects, который содержит метод append. Пользовательские типы объектов, используемые с пакетом 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 вызывает этот метод с именем и значением, хранящимися в данный момент в Message, когда заголовок запрашивается прикладной программой, и то, что возвращает метод, передаётся обратно приложению в качестве значения запрашиваемого заголовка. Обратите внимание, что в Message может быть несколько заголовков с одним и тем же именем; методу передаются конкретные имя и значение заголовка, который будет возвращён приложению.

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

Реализация по умолчанию отсутствует

fold(name, value)

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

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

fold_binary(name, value)

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

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

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) двоичными данными, которые он может содержать.

Экземпляр Compat32 предоставляется как константа модуля:

email.policy.compat32

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

Примечание

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 электронной почты. Они включают (но не ограничиваются) RFC 5322, RFC 2047 и текущим RFC MIME.

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

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

utf8

If False, follow RFC 5322, supporting non-ASCII characters in headers by encoding them as “encoded words”. If True, follow RFC 6532 and use utf-8 encoding for headers. Messages formatted in this way may be passed to SMTP servers that support the SMTPUTF8 extension (RFC 6531).

refold_source

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

none все исходные значения используют исходное сворачивание
long исходные значения, имеющие строки длиннее max_line_length, будут свёрнуты заново
all все значения сворачиваются заново.

Значение по умолчанию: long.

header_factory

A callable that takes two arguments, name and value, where name is a header field name and value is an unfolded header field value, and returns a string subclass that represents that header. A default header_factory (see headerregistry) is provided that understands some of the RFC 5322 header field types. (Currently address fields and date fields have special treatment, while all other fields are treated as unstructured. This list will be completed before the extension is marked stable.)

content_manager

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

Новое в версии 3.4.

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

header_max_count(name)

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

header_source_parse(sourcelines)

Реализация этого метода такая же, как и для Compat32 политики.

header_store_parse(name, value)

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

header_fetch_parse(name, value)

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

fold(name, value)

Свёртка заголовков управляется настройкой политики refold_source. Значение считается «исходным значением» тогда и только тогда, когда у него нет атрибута name (наличие атрибута name означает, что это объект заголовка того или иного вида). Если исходное значение необходимо пересвернуть в соответствии с политикой, оно преобразуется в объект заголовка путём передачи имени и значения (с удалёнными символами 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

Подходит для сериализации сообщений в соответствии с 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 пакета email изменяется по сравнению с API Python 3.2 следующим образом:

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

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

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