email.policy: Policy Objects

Нове в версії 3.3.

Вихідний код: Lib/email/policy.py


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

Об’єкти політики надають пакету електронної пошти гнучкість для обробки всіх цих різнорідних випадків використання.

Об’єкт Policy інкапсулює набір атрибутів і методів, які контролюють поведінку різних компонентів пакета електронної пошти під час використання. Екземпляри Policy можна передати різним класам і методам у пакеті електронної пошти, щоб змінити типову поведінку. Нижче описано встановлені значення та їх значення за замовчуванням.

Існує політика за замовчуванням, яка використовується всіма класами в пакеті електронної пошти. Для всіх класів 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, який є копією оригіналу, але зі зміненими значеннями вказаних атрибутів .

Як приклад, наступний код можна використати для читання повідомлення електронної пошти з файлу на диску та передачі його системній програмі 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, що дозволяє перевизначати політику для цього методу. Наприклад, у наступному коді використовується метод 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

Керує типом кодувань передачі вмісту, які можуть або повинні використовуватися. Можливі значення:

7 біт

усі дані мають бути «7-бітними чистими» (лише ASCII). Це означає, що там, де це необхідно, дані будуть закодовані з використанням кодування для друку в цитатах або кодування base64.

8 біт

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

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

raise_on_defect

Якщо True, будь-які виявлені дефекти визначатимуться як помилки. Якщо False (за замовчуванням), дефекти будуть передані в метод register_defect().

mangle_from_

Якщо True, рядки, що починаються з «From « у тілі, екрануються шляхом розміщення > перед ними. Цей параметр використовується, коли повідомлення серіалізується генератором. Типове значення: False.

Нове в версії 3.5: The mangle_from_ parameter.

message_factory

Фабрична функція для створення нового порожнього об’єкта повідомлення. Використовується аналізатором під час створення повідомлень. За замовчуванням None, у цьому випадку використовується Message.

Нове в версії 3.6.

verify_generated_headers

If True (the default), the generator will raise HeaderWriteError instead of writing a header that is improperly folded or delimited, such that it would be parsed as multiple headers or joined with adjacent data. Such headers can be generated by custom header classes or bugs in the email module.

As it’s a security feature, this defaults to True even in the Compat32 policy. For backwards compatible, but unsafe, behavior, it must be set to False explicitly.

Нове в версії 3.9.20.

Наступний метод Policy призначений для виклику за допомогою коду за допомогою бібліотеки електронної пошти для створення екземплярів політики з настроюваними налаштуваннями:

clone(**kw)

Повертає новий екземпляр Policy, атрибути якого мають ті самі значення, що й поточний екземпляр, за винятком тих випадків, коли ці атрибути отримують нові значення аргументами ключового слова.

Решта методів Policy викликається кодом пакета електронної пошти і не призначена для виклику програмою, яка використовує пакет електронної пошти. Спеціальна політика повинна реалізовувати всі ці методи.

handle_defect(obj, defect)

Handle a defect found on obj. When the email package calls this method, defect will always be a subclass of Defect.

Стандартна реалізація перевіряє прапорець raise_on_defect. Якщо значення True, defect створюється як виняток. Якщо значення False (за замовчуванням), obj і defect передаються в register_defect().

register_defect(obj, defect)

Register a defect on obj. In the email package, defect will always be a subclass of Defect.

Стандартна реалізація викликає метод append атрибута defects obj. Коли пакет електронної пошти викликає handle_defect, obj зазвичай матиме атрибут defects, який має метод append. Спеціальні типи об’єктів, які використовуються з пакетом електронної пошти (наприклад, спеціальні об’єкти Message), також повинні надавати такий атрибут, інакше дефекти в проаналізованих повідомленнях призведуть до неочікуваних помилок.

header_max_count(name)

Повертає максимально дозволену кількість заголовків із назвою ім’я.

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

Оскільки за замовчуванням Message.__setitem__ додає значення до списку заголовків, легко створити дублікати заголовків, не усвідомлюючи цього. Цей метод дозволяє обмежити певні заголовки в кількості екземплярів цього заголовка, які можна додати до повідомлення програмним шляхом. (Обмеження не дотримується синтаксичним аналізатором, який сумлінно створить стільки заголовків, скільки існує в повідомленні, що аналізується.)

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

header_source_parse(sourcelines)

Пакет електронної пошти викликає цей метод зі списком рядків, кожен рядок закінчується символами розділення рядків, знайденими в джерелі, що аналізується. Перший рядок містить назву заголовка поля та роздільник. Усі пробіли в джерелі збережено. Метод має повертати кортеж (name, value), який має зберігатися в Message для представлення аналізованого заголовка.

Якщо реалізація бажає зберегти сумісність із існуючими політиками пакетів електронної пошти, ім’я має бути ім’ям із збереженням регістру (усі символи до роздільника «:), тоді як значення має бути розгорнутим значенням (усі символи-роздільники рядків видалено, але пробіли збережено без змін), видалено пробіли на початку.

вихідні лінії можуть містити сурогатні двійкові дані.

Реалізації за замовчуванням немає

header_store_parse(name, value)

Пакет електронної пошти викликає цей метод із назвою та значенням, наданими прикладною програмою, коли прикладна програма програмно змінює повідомлення (на відміну від повідомлення, створеного аналізатором). Метод має повертати кортеж (name, value), який має зберігатися в Message для представлення заголовка.

Якщо реалізація бажає зберегти сумісність із існуючими політиками пакетів електронної пошти, ім’я та значення мають бути рядками або підкласами рядків, які не змінюють вміст переданих аргументів.

Реалізації за замовчуванням немає

header_fetch_parse(name, value)

Пакет електронної пошти викликає цей метод із ім’ям і значенням, які наразі зберігаються в Message, коли прикладна програма запитує цей заголовок, і те, що метод повертає, передається назад до програми як значення заголовка, що витягується. Зауважте, що в Повідомленні може бути більше одного заголовка з однаковою назвою; методу передається конкретне ім’я та значення заголовка, призначеного для повернення до програми.

значення може містити сурогатні екрановані двійкові дані. У значенні, яке повертає метод, не повинно бути сурогатних двійкових даних.

Реалізації за замовчуванням немає

fold(name, value)

Пакет електронної пошти викликає цей метод із ім’ям і значенням, які наразі зберігаються в Повідомленні для заданого заголовка. Метод має повернути рядок, який представляє цей заголовок, «згорнутий» правильно (відповідно до налаштувань політики), складаючи ім’я з значенням і вставляючи символи linesep у відповідних місцях. Перегляньте RFC 5322 для обговорення правил згортання заголовків електронних листів.

значення може містити сурогатні екрановані двійкові дані. У рядку, який повертає метод, не повинно бути сурогатних двійкових даних.

fold_binary(name, value)

Те саме, що fold(), за винятком того, що повернуте значення має бути об’єктом bytes, а не рядком.

значення може містити сурогатні екрановані двійкові дані. Вони можуть бути перетворені назад у двійкові дані у повернутому об’єкті 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

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

довгий

вихідні значення, які мають будь-який рядок, довший за max_line_length, будуть повторно згорнуті

все

усі значення перескладають.

Типовим є 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 без урахування регістру, значення повертається без змін. В іншому випадку ім’я та значення передаються до header_factory, а отриманий об’єкт заголовка повертається як значення. У цьому випадку виникає ValueError, якщо вхідне значення містить символи CR або LF.

header_fetch_parse(name, value)

Якщо значення має атрибут name, воно повертається до незміненого. В іншому випадку ім’я та значення з видаленими будь-якими символами 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

Підходить для серіалізації повідомлень відповідно до 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. Так само заголовку може бути призначено нове значення або створений новий заголовок за допомогою рядка Юнікод, і політика подбає про перетворення рядка Юнікод у правильну форму, закодовану 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. В іншому випадку використовується вихідний вихідний заголовок із наявними розривами рядків і будь-якими (недійсними RFC) двійковими даними, які він може містити.

email.policy.compat32

Екземпляр Compat32, що забезпечує зворотну сумісність із поведінкою пакета електронної пошти в Python 3.2.

Виноски

1

Спочатку додано в 3.3 як попередню функцію.