email.header: Интернационализированные заголовки

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


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

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

RFC 2822 - это базовый стандарт, описывающий формат сообщений электронной почты. Он происходит от более старого стандарта RFC 822, который получил широкое распространение в то время, когда большинство электронных сообщений состояло только из символов ASCII. RFC 2822 - это спецификация, написанная в предположении, что электронная почта содержит только 7-битные символы ASCII.

Конечно, с распространением электронной почты по всему миру, она стала интернационализированной, так что теперь в сообщениях электронной почты можно использовать наборы символов, специфичные для конкретного языка. Базовый стандарт по-прежнему требует, чтобы сообщения электронной почты передавались с использованием только 7-битных символов ASCII, поэтому было написано множество RFC, описывающих, как кодировать сообщения электронной почты, содержащие символы, отличные от ASCII, в RFC 2822-совместимый формат. Эти RFC включают RFC 2045, RFC 2046, RFC 2047 и RFC 2231. Пакет email поддерживает эти стандарты в своих модулях email.header и email.charset.

Если вы хотите включить в заголовки электронной почты символы, отличные от ASCII, например, в поля Subject или To, вам следует использовать класс Header и присвоить поле в объекте Message экземпляру Header вместо использования строки для значения заголовка. Импортируйте класс Header из модуля email.header. Например:

>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

Заметили, как мы хотели, чтобы поле Subject содержало символ, не являющийся символом ASCII? Мы сделали это, создав экземпляр Header и передав ему набор символов, в котором была закодирована байтовая строка. Когда последующий экземпляр Message был сплющен, поле Subject было правильно закодировано RFC 2047. Почтовые программы, поддерживающие MIME, будут показывать этот заголовок, используя встроенный символ ISO-8859-1.

Вот описание класса Header:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

Создайте MIME-совместимый заголовок, который может содержать строки в различных наборах символов.

Необязательное значение s - начальное значение заголовка. Если None (по умолчанию), начальное значение заголовка не устанавливается. В дальнейшем вы можете добавлять к заголовку с помощью вызовов метода append(). s может быть экземпляром bytes или str, но семантику см. в документации append().

Необязательный charset служит двум целям: он имеет то же значение, что и аргумент charset метода append(). Он также задает набор символов по умолчанию для всех последующих вызовов append(), в которых аргумент charset опущен. Если charset не указан в конструкторе (по умолчанию), набор символов us-ascii используется как в качестве начального набора символов s, так и по умолчанию для последующих вызовов append().

Максимальная длина строки может быть задана явно через maxlinelen. Для разбиения первой строки на более короткие значения (для учета заголовка поля, не включенного в s, например, Subject) передайте имя поля в header_name. По умолчанию maxlinelen равно 76, а значение по умолчанию для header_name равно None, что означает, что оно не учитывается для первой строки длинного разделенного заголовка.

Необязательный continuation_ws должен быть RFC 2822-совместимым со сворачиванием пробельных символов, и обычно представляет собой либо пробел, либо символ жесткой табуляции. Этот символ будет добавляться к строкам продолжения. По умолчанию continuation_ws - это один символ пробела.

Необязательные ошибки передаются прямо в метод append().

append(s, charset=None, errors='strict')

Добавьте строку s к заголовку MIME.

Необязательный charset, если задан, должен быть экземпляром Charset (см. email.charset) или именем набора символов, который будет преобразован в экземпляр Charset. Значение None (по умолчанию) означает, что используется charset, заданный в конструкторе.

s может быть экземпляром bytes или str. Если это экземпляр bytes, то charset - это кодировка этой байтовой строки, и если строка не может быть декодирована с помощью этого набора символов, то будет вызвана ошибка UnicodeError.

Если s является экземпляром str, то charset является подсказкой, определяющей набор символов в строке.

В любом случае, при создании RFC 2822-совместимого заголовка с использованием правил RFC 2047, строка будет закодирована с использованием выходного кодека charset. Если строка не может быть закодирована с помощью выходного кодека, будет выдана ошибка UnicodeError.

Необязательные errors передаются в качестве аргумента errors в вызов декодирования, если s является байтовой строкой.

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

Кодировать заголовок сообщения в формат, соответствующий RFC, возможно, обертывая длинные строки и инкапсулируя не-ASCII части в кодировки base64 или quoted-printable.

Необязательные splitchars - это строка, содержащая символы, которым алгоритм разбиения должен придать дополнительный вес при обычном обертывании заголовка. Это очень грубая поддержка «синтаксических разрывов более высокого уровня» RFC 2822: точки разделения, которым предшествует сплитчар, предпочитаются при разбиении строки, причем символы предпочитаются в том порядке, в котором они появляются в строке. Пробел и табуляция могут быть включены в строку, чтобы указать, следует ли отдавать предпочтение одному из них перед другим в качестве точки разделения, когда другие символы разделения не встречаются в разделяемой строке. Splitchars не влияет на строки с кодировкой RFC 2047.

maxlinelen, если задано, переопределяет значение экземпляра для максимальной длины строки.

linesep задает символы, используемые для разделения строк свернутого заголовка. По умолчанию используется наиболее полезное значение для кода приложения Python (\n), но можно указать \r\n, чтобы получить заголовки с разделителями строк, соответствующими требованиям RFC.

Изменено в версии 3.2: Добавлен аргумент linesep.

Класс Header также предоставляет ряд методов для поддержки стандартных операторов и встроенных функций.

__str__()

Возвращает аппроксимацию Header в виде строки, используя неограниченную длину строки. Все части преобразуются в юникод с использованием указанной кодировки и соединяются соответствующим образом. Все фрагменты с кодировкой 'unknown-8bit' декодируются как ASCII с помощью обработчика ошибок 'replace'.

Изменено в версии 3.2: Добавлена обработка кодировки 'unknown-8bit'.

__eq__(other)

Этот метод позволяет сравнить два экземпляра Header на равенство.

__ne__(other)

Этот метод позволяет сравнить два экземпляра Header на предмет неравенства.

Модуль email.header также предоставляет следующие удобные функции.

email.header.decode_header(header)

Декодирование значения заголовка сообщения без преобразования набора символов. Значение заголовка находится в header.

Эта функция возвращает список пар (decoded_string, charset), содержащих каждую из декодированных частей заголовка. charset - None для некодированных частей заголовка, иначе строка в нижнем регистре, содержащая имя набора символов, указанного в кодированной строке.

Вот пример:

>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[(b'p\xf6stal', 'iso-8859-1')]
email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')

Создайте экземпляр Header из последовательности пар, возвращенных decode_header().

decode_header() принимает строку значений заголовка и возвращает последовательность пар формата (decoded_string, charset), где charset - имя набора символов.

Эта функция принимает одну из этих последовательных пар и возвращает экземпляр Header. Необязательные maxlinelen, header_name и continuation_ws такие же, как в конструкторе Header.

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