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

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

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


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

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

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

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

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

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

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

В первой части этой документации рассматриваются функции Policy, abstract base class, которые определяют функции, общие для всех объектов политики, включая compat32. Это включает в себя определенные методы перехвата, которые вызываются внутри почтового пакета, которые пользовательская политика может переопределить для получения другого поведения. Во второй части описываются конкретные классы 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() и семантики конструктора.

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

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

max_line_length

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

linesep

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

cte_type

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

7bit

все данные должны быть «чистыми в 7 бит» (только в формате ASCII). Это означает, что при необходимости данные будут закодированы с использованием либо кавычек для печати, либо кодировки 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.

message_factory

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

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

verify_generated_headers

Если True (значение по умолчанию), генератор выдаст HeaderWriteError вместо записи заголовка, который неправильно свернут или разделен, так что он будет проанализирован как несколько заголовков или объединен со смежными данными. Такие заголовки могут быть сгенерированы пользовательскими классами заголовков или ошибками в модуле email.

Поскольку это функция безопасности, значение по умолчанию равно True даже в политике Compat32. Для обратной совместимости, но небезопасного поведения, оно должно быть явно установлено на False.

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

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

clone(**kw)

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

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

handle_defect(obj, defect)

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

Реализация по умолчанию проверяет флаг raise_on_defect. Если он равен True, то defect вызывается как исключение. Если это 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)

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

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

исходные данные могут содержать двоичные данные surrogateescape.

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

header_store_parse(name, value)

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

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

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

header_fetch_parse(name, value)

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

значение может содержать двоичные данные в формате surrogateescape. В значении, возвращаемом методом, не должно быть двоичных данных в формате surrogateescape.

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

fold(name, value)

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

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

fold_binary(name, value)

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

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

class email.policy.EmailPolicy(**kw)

Этот конкретный Policy обеспечивает поведение, которое должно полностью соответствовать текущим запросам по электронной почте. К ним относятся (но не ограничиваются ими)) RFC 5322, RFC 2047, и текущие запросы по 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, он вызывает соответствующий метод этого объекта, передавая ему объект message в качестве первого аргумента и любые аргументы или ключевые слова, которые были ему переданы в качестве дополнительных аргументов. По умолчанию для 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 без учета регистра, значение возвращается без изменений. В противном случае имя и значение передаются в header_factory, а результирующий объект заголовка возвращается в качестве значения. В этом случае ValueError генерируется, если входное значение содержит символы CR или LF.

header_fetch_parse(name, value)

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

fold(name, value)

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

email.policy.default

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

email.policy.SMTP

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

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

class email.policy.Compat32(**kw)

Этот конкретный Policy является политикой обратной совместимости. Он повторяет поведение почтового пакета в Python 3.2. Модуль policy также определяет экземпляр этого класса, compat32, который используется в качестве политики по умолчанию. Таким образом, поведение почтового пакета по умолчанию заключается в поддержании совместимости с 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. В противном случае используется исходный заголовок source с существующими переносами строк и любыми (недопустимыми по RFC) двоичными данными, которые он может содержать.

email.policy.compat32

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

Сноски

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