email.headerregistry :自定义头对象

源代码: Lib/email/headerregistry.py


3.6 新版功能: 1

头由自定义的子类表示 str . 用于表示给定头的特定类由 header_factory 的 policy 在创建标题时生效。本节记录了 header_factory 通过电子邮件包实现处理 RFC 5322 兼容的电子邮件消息,它不仅为各种头类型提供定制的头对象,还为应用程序添加自己的定制头类型提供扩展机制。

当使用从中派生的任何策略对象时 EmailPolicy ,所有标题都由 HeaderRegistry 并拥有 BaseHeader 作为他们最后的基础阶级。每个头类都有一个由头类型决定的附加基类。例如,许多头都有类 UnstructuredHeader 作为他们的另一个基础阶级。头的专用第二类由头的名称确定,使用存储在 HeaderRegistry . 对于典型的应用程序,所有这些都是透明管理的,但是提供了用于修改默认行为的接口,以供更复杂的应用程序使用。

下面的部分首先记录头基类及其属性,然后是用于修改 HeaderRegistry 最后是用于表示从结构化头解析的数据的支持类。

class email.headerregistry.BaseHeader(name, value)

name 和 value 被传递给 BaseHeader 从 header_factory 调用。任何header对象的字符串值都是 value 完全解码为Unicode。

此基类定义以下只读属性:

name

头的名称(字段中“:”之前的部分)。这正是 header_factory 需要 name 也就是说,箱子是保存着的。

defects

一个元组 HeaderDefect 实例报告分析期间发现的任何RFC遵从性问题。电子邮件包试图完成有关检测合规性问题的工作。查看 errors 讨论可能报告的缺陷类型的模块。

max_count

此类型的头的最大数目可以相同 name . 一个值 None 意味着无限。这个 BaseHeader 此属性的值为 None ;预期专门化的头类将根据需要重写该值。

BaseHeader 还提供以下方法,该方法由电子邮件库代码调用,通常不应由应用程序调用:

fold(*, policy)

返回包含 linesep 按要求的字符,以便根据 policy . 一 cte_type 属于 8bit 将被视为 7bit ,因为头不能包含任意二进制数据。如果 utf8 是 False ,非ASCII数据将 RFC 2047 编码的。

BaseHeader 本身不能用于创建头对象。它定义了一个协议,每个专门的头与之合作,以生成头对象。明确地, BaseHeader 要求专业类提供 classmethod() 已命名 parse . 此方法调用如下:

parse(string, kwds)

kwds 是包含一个预初始化密钥的字典, defects . defects 是空列表。解析方法应该将检测到的任何缺陷附加到此列表中。返回时, kwds 词典 must 至少包含键的值 decoded 和 defects . decoded 应为头的字符串值(即完全解码为Unicode的头值)。parse方法应该假设 string 可能包含内容传输编码的部分,但也应正确处理所有有效的Unicode字符,以便它可以解析未编码的头值。

BaseHeader 的 __new__ 然后创建头实例,并调用 init 方法。专业课只需要提供 init 方法,如果它希望设置超出 BaseHeader 本身。这样的 init 方法应如下所示:

def init(self, /, *args, **kw):
    self._myattr = kw.pop('myattr')
    super().init(*args, **kw)

也就是说,专业课在 kwds 应删除并处理字典,以及 kw (和 args )传递给 BaseHeader init 方法。

class email.headerregistry.UnstructuredHeader

“非结构化”头是中的默认头类型 RFC 5322 .任何没有指定语法的头都被视为非结构化的。非结构化头的典型示例是 Subject 标题。

在 RFC 5322 ,非结构化头是一个在ASCII字符集中运行的任意文本。 RFC 2047 但是,有一个 RFC 5322 将非ASCII文本编码为头值内的ASCII字符的兼容机制。当A value 将包含编码的单词传递给构造函数, UnstructuredHeader 解析器将这些编码的单词转换为Unicode,然后 RFC 2047 非结构化文本规则。解析器使用启发式方法尝试对某些不兼容的编码字进行解码。在这种情况下,缺陷会被注册,也会在编码字或非编码文本中出现诸如无效字符等问题。

此头类型不提供其他属性。

class email.headerregistry.DateHeader

RFC 5322 为电子邮件头中的日期指定非常特定的格式。这个 DateHeader 解析器识别出日期格式,并识别出一些有时在“野外”中发现的变量形式。

此头类型提供以下附加属性:

datetime

如果可以将头值识别为一个或另一个窗体的有效日期,则此属性将包含 datetime 表示该日期的实例。如果输入日期的时区指定为 -0000 (表示它是在UTC中,但不包含有关源时区的信息),然后 datetime 将是天真的 datetime . 如果找到特定时区偏移(包括 +0000 ) datetime 将包含一个已知 datetime 使用的 datetime.timezone 记录时区偏移。

这个 decoded 头的值是通过格式化 datetime 根据 RFC 5322 规则;也就是说,它设置为:

email.utils.format_datetime(self.datetime)

创建一个 DateHeader , value 可能是 datetime 实例。这意味着,例如,以下代码是有效的,并按预期执行:

msg['Date'] = datetime(2011, 7, 15, 21)

因为这是一个幼稚的 datetime 它将被解释为一个UTC时间戳,结果值的时区为 -0000 . 更有用的是使用 localtime() 函数来自 utils 模块:

msg['Date'] = utils.localtime()

此示例使用当前时区偏移量将日期标题设置为当前时间和日期。

class email.headerregistry.AddressHeader

地址头是最复杂的结构化头类型之一。这个 AddressHeader 类为任何地址头提供通用接口。

此头类型提供以下附加属性:

groups

一个元组 Group 对在头值中找到的地址和组进行编码的对象。不属于组的地址在此列表中表示为单个地址 Groups 谁的 display_name 是 None .

addresses

一个元组 Address 对象对头值中的所有单个地址进行编码。如果头值包含任何组,则该组中的单个地址将包含在该值中该组出现的位置的列表中(即,地址列表被“扁平”为一维列表)。

这个 decoded 头的值将所有编码的单词解码为Unicode。 idna 编码的域名也被解码为Unicode。这个 decoded 值由 join 在 str 元素的值 groups 属性与 ', ' .

列表 Address 和 Group 可以使用任意组合的对象来设置地址头的值。 Group 对象的对象 display_name 是 None 将被解释为单个地址,允许使用从 groups 源头的属性。

class email.headerregistry.SingleAddressHeader

一个子类 AddressHeader 添加了一个附加属性:

address

由头值编码的单个地址。如果头值实际包含多个地址(在默认情况下,这将违反RFC policy ,访问此属性将导致 ValueError .

上面的许多类也有一个 Unique 变量(例如, UniqueUnstructuredHeader )唯一的区别是 Unique 变体, max_count 设置为1。

class email.headerregistry.MIMEVersionHeader

对于 MIME-Version 头,那就是 1.0 . 为了将来的校对,这个头类支持其他有效的版本号。如果版本号的有效值为 RFC 2045 ,则header对象将具有以下属性的非``none``值:

version

将版本号作为字符串,删除任何空白和/或注释。

major

主版本号为整数

minor

作为整数的次要版本号

class email.headerregistry.ParameterizedMIMEHeader

所有的mime头都以前缀“content-”开头。每个特定的头都有一个特定的值,在该头的类下进行描述。有些还可以获取具有通用格式的补充参数列表。这个类作为所有接受参数的mime头的基础。

params

将参数名映射到参数值的字典。

class email.headerregistry.ContentTypeHeader

A ParameterizedMIMEHeader 类处理 Content-Type 标题。

content_type

表单中的内容类型字符串 maintype/subtype .

maintype
subtype
class email.headerregistry.ContentDispositionHeader

A ParameterizedMIMEHeader 类处理 Content-Disposition 标题。

content_disposition

inline 和 attachment 是常用的唯一有效值。

class email.headerregistry.ContentTransferEncoding

处理 Content-Transfer-Encoding 标题。

cte

有效值为 7bit , 8bit , base64 和 quoted-printable . 见 RFC 2045 更多信息。

class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)

这是一家工厂 EmailPolicy 默认情况下。 HeaderRegistry 生成用于动态创建头实例的类,使用 base_class 以及从它所保存的注册表中检索到的专用类。当给定的头名称未出现在注册表中时,由指定的类 default_class 用作专业课。什么时候? use_default_map 是 True (默认值)初始化期间,头名称到类的标准映射将复制到注册表中。 base_class 始终是生成类中的最后一个类 __bases__ 名单。

默认映射为:

主题

UniqueUnstructuredHeader

日期

UniqueDateHeader

怨恨日期

DateHeader

奥利格日期

UniqueDateHeader

发件人

UniqueSingleAddressHeader

怨恨发送者

SingleAddressHeader

到

UniqueAddressHeader

怨恨

AddressHeader

复写的副本

UniqueAddressHeader

怨恨CC

AddressHeader

基底细胞癌

UniqueAddressHeader

重新发送密件抄送

AddressHeader

从

UniqueAddressHeader

怨恨

AddressHeader

答复

UniqueAddressHeader

MIME版本

MIMEVersionHeader

内容类型

ContentTypeHeader

内容处置

ContentDispositionHeader

内容传输编码

ContentTransferEncodingHeader

消息ID

MessageIDHeader

HeaderRegistry 有以下方法:

map_to_type(self, name, cls)

name 是要映射的头的名称。它将在注册表中转换为小写。 cls 是要使用的专业类,以及 base_class ,以创建用于实例化匹配的头的类 name .

__getitem__(name)

构造并返回一个类来处理创建 name 标题。

__call__(name, value)

检索与 name 从注册表(使用 default_class 如果 name 不会出现在注册表中)并用 base_class 若要生成类,请调用构造类的构造函数,并将其传递给同一参数列表,最后返回由此创建的类实例。

以下类是用于表示从结构化头文件解析的数据的类,通常,应用程序可以使用这些类来构造结构化值以分配给特定头文件。

class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)

用于表示电子邮件地址的类。地址的一般形式是:

[display_name] <username@domain>

或:

username@domain

其中每个部分必须符合 RFC 5322 .

为了方便 addr_spec 可以指定而不是 用户名 和 域 ,在这种情况下 用户名 和 域 将从中分析 addr_spec . 安 addr_spec 必须是正确的RFC引用字符串;如果不是 Address 将引发错误。允许使用Unicode字符,并且在序列化时将对其进行属性编码。但是,根据RFC,Unicode是 not 地址的用户名部分允许。

display_name

地址的显示名称部分(如果有的话),删除所有引用。如果地址没有显示名称,则此属性将为空字符串。

username

这个 username 地址的一部分,删除所有引用。

domain

这个 domain 地址的一部分。

addr_spec

这个 username@domain 地址的一部分,正确引用作为裸地址(上面显示的第二种格式)。此属性不可变。

__str__()

这个 str 对象的值是根据 RFC 5322 规则,但不包含任何非ASCII字符的内容传输编码。

支持SMTP (RFC 5321 ) Address 处理一个特殊情况:如果 username 和 domain 都是空字符串(或 None )的字符串值, Address 是 <> .

class email.headerregistry.Group(display_name=None, addresses=None)

用于表示地址组的类。地址组的一般形式是:

display_name: [address-list];

为了方便处理由组和单个地址混合组成的地址列表,a Group 也可以通过设置来表示不属于组的单个地址 display_name 到 None 并提供单一地址列表 地址 .

display_name

这个 display_name 这个组的如果是 None 只有一个 Address 在里面 addresses 然后 Group 表示不在组中的单个地址。

addresses

可能是空的 Address 表示组中地址的对象。

__str__()

这个 str A值 Group 格式设置依据 RFC 5322 ,但没有任何非ASCII字符的内容传输编码。如果 display_name 没有也有单人间吗 Address 在 addresses 清单 str 值将与 str 那个单曲 Address .

脚注

1

最初在3.3中作为 provisional module