email.policy
: Policy 对象¶
3.3 版本新增。
源代码: Lib/email/policy.py
email
包的主要重点是处理各种电子邮件和 MIME RFC 中描述的电子邮件消息。然而,电子邮件消息的一般格式(一个由名称后跟冒号,后跟值的头部字段组成,整个块后跟一个空行和一个任意的“主体”),是一种在电子邮件领域之外也很有用的格式。其中一些用法相当符合主要的电子邮件 RFC,有些则不然。即使在使用电子邮件时,有时也需要打破对 RFC 的严格遵守,例如生成与不遵循标准或以违反标准的方式实现您想要使用的扩展的电子邮件服务器互操作的电子邮件。
Policy 对象为 email 包提供了处理所有这些不同用例的灵活性。
Policy
对象封装了一组属性和方法,这些属性和方法控制 email 包在使用期间的各种组件的行为。Policy
实例可以传递给 email 包中的各种类和方法,以更改默认行为。下面描述了可设置的值及其默认值。
email 包中的所有类都使用默认的 policy。 对于所有 parser
类和相关的便捷函数,以及 Message
类,这是 Compat32
policy,通过其对应的预定义实例 compat32
。此 policy 提供与 Python 3.3 之前的 email 包版本的完全向后兼容性(在某些情况下,包括 bug 兼容性)。
对于 EmailMessage
,*policy* 关键字的此默认值为 EmailPolicy
policy,通过其预定义实例 default
。
当创建 Message
或 EmailMessage
对象时,它会获取 policy。 如果消息是由 parser
创建的,则传递给解析器的 policy 将是其创建的消息所使用的 policy。 如果消息是由程序创建的,则可以在创建时指定 policy。 当将消息传递给 generator
时,生成器默认使用消息中的 policy,但您也可以将特定的 policy 传递给生成器,这将覆盖存储在消息对象上的 policy。
对于 email.parser
类和解析器便捷函数,*policy* 关键字的默认值将在未来版本的 Python 中更改。 因此,在调用 parser
模块中描述的任何类和函数时,您应该始终明确指定您想要使用的 policy。
本文档的第一部分介绍了 Policy
的特性,它是一个 抽象基类,定义了所有 policy 对象通用的特性,包括 compat32
。这包括由 email 包在内部调用的某些钩子方法,自定义 policy 可以覆盖这些方法以获得不同的行为。第二部分描述了具体类 EmailPolicy
和 Compat32
,它们分别实现提供标准行为和向后兼容行为和特性的钩子。
Policy
实例是不可变的,但可以克隆,接受与类构造函数相同的关键字参数,并返回一个新的 Policy
实例,该实例是原始实例的副本,但指定了已更改的属性值。
例如,以下代码可用于从磁盘上的文件中读取电子邮件消息,并将其传递给 Unix 系统上的系统 sendmail
程序
>>> 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
在创建要输入到 sendmail
的 stdin
的二进制字符串时使用符合 RFC 的行分隔符字符,其中默认 policy 将使用 \n
行分隔符。
某些 email 包方法接受 *policy* 关键字参数,允许为该方法覆盖 policy。 例如,以下代码使用上一个示例中 *msg* 对象的 as_bytes()
方法,并使用其运行平台的本机行分隔符将消息写入文件
>>> import os
>>> with open('converted.txt', 'wb') as f:
... f.write(msg.as_bytes(policy=msg.policy.clone(linesep=os.linesep)))
17
也可以使用加法运算符组合 Policy 对象,生成一个 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)¶
这是所有 policy 类的 抽象基类。它为几个琐碎的方法提供默认实现,以及不可变属性、
clone()
方法和构造函数语义的实现。可以将各种关键字参数传递给 policy 类的构造函数。可以指定的参数是此类上的任何非方法属性,以及具体类上的任何其他非方法属性。构造函数中指定的值将覆盖相应属性的默认值。
此类定义了以下属性,因此可以将以下值传递给任何 policy 类的构造函数
- linesep¶
用于终止序列化输出中行的字符串。默认值为
\n
,因为这是 Python 使用的内部行尾规范,尽管 RFC 需要\r\n
。
- cte_type¶
控制可能使用或必须使用的内容传输编码类型。可能的值为
7bit
所有数据必须是“7 位干净”(仅限 ASCII)。这意味着在必要时,数据将使用 quoted-printable 或 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 版本中添加。
- verify_generated_headers¶
如果为
True
(默认值),生成器将引发HeaderWriteError
,而不是写入不正确折叠或分隔的标头,以致它将被解析为多个标头或与相邻数据连接。此类标头可以通过自定义标头类或email
模块中的错误生成。由于它是一个安全功能,即使在
Compat32
策略中,此值也默认为True
。对于向后兼容但存在不安全行为的情况,必须显式将其设置为False
。在 3.13 版本中添加。
以下
Policy
方法旨在由使用 email 库的代码调用,以创建具有自定义设置的策略实例其余的
Policy
方法由 email 包代码调用,不打算由使用 email 包的应用程序调用。自定义策略必须实现所有这些方法。- handle_defect(obj, defect)¶
处理在 obj 上找到的 defect。当 email 包调用此方法时,defect 将始终是
Defect
的子类。默认实现检查
raise_on_defect
标志。如果为True
,则将 defect 作为异常引发。如果为False
(默认值),则将 obj 和 defect 传递给register_defect()
。
- register_defect(obj, defect)¶
在 obj 上注册一个 defect。在 email 包中,defect 将始终是
Defect
的子类。默认实现调用 obj 的
defects
属性的append
方法。当 email 包调用handle_defect
时,obj 通常会有一个具有append
方法的defects
属性。与 email 包一起使用的自定义对象类型(例如,自定义Message
对象)也应提供这样的属性,否则解析消息中的缺陷将引发意外错误。
- header_max_count(name)¶
返回名为 name 的标头允许的最大数量。
当将标头添加到
EmailMessage
或Message
对象时调用。如果返回的值不是0
或None
,并且已经存在多个名为 name 的标头大于或等于返回的值,则会引发ValueError
。由于
Message.__setitem__
的默认行为是将值附加到标头列表,因此很容易在不知不觉中创建重复的标头。此方法允许对某些标头进行限制,以限制可以通过编程方式添加到Message
的该标头的实例数量。(解析器不会观察此限制,它会忠实地生成消息中存在的尽可能多的标头。)默认实现为所有标头名称返回
None
。
- header_source_parse(sourcelines)¶
email 包使用一个字符串列表调用此方法,每个字符串都以在要解析的源中找到的行分隔符字符结尾。第一行包括字段标头名称和分隔符。源中的所有空格都会被保留。该方法应返回要存储在
Message
中以表示已解析标头的(name, value)
元组。如果实现希望保留与现有 email 包策略的兼容性,则 name 应该是保留大小写的名称(直到 ‘
:
’ 分隔符的所有字符),而 value 应该是不折叠的值(删除了所有行分隔符字符,但保留了空格),并删除了前导空格。sourcelines 可能包含 surrogateescaped 二进制数据。
没有默认实现
- header_store_parse(name, value)¶
当应用程序在以编程方式修改
Message
(而不是由解析器创建的Message
)时,email 包使用应用程序提供的名称和值调用此方法。该方法应返回要存储在Message
中以表示标头的(name, value)
元组。如果实现希望保留与现有 email 包策略的兼容性,则 name 和 value 应该是字符串或不更改传入参数内容的字符串子类。
没有默认实现
- header_fetch_parse(name, value)¶
当应用程序请求该标头时,email 包会使用当前存储在
Message
中的name 和 value 调用此方法,并且该方法返回的任何内容都会作为检索到的标头值传递回应用程序。请注意,Message
中可能存储了多个具有相同名称的标头;该方法会传递特定标头的名称和值,该标头注定要返回给应用程序。value 可能包含 surrogateescaped 二进制数据。该方法返回的值中不应包含 surrogateescaped 二进制数据。
没有默认实现
- class email.policy.EmailPolicy(**kw)¶
这个具体的
Policy
提供了旨在完全符合当前电子邮件 RFC 的行为。这些包括(但不限于)RFC 5322、RFC 2047 和当前的 MIME RFC。此策略添加了新的标头解析和折叠算法。标头不再是简单的字符串,而是
str
子类,其属性取决于字段的类型。解析和折叠算法完全实现了 RFC 2047 和 RFC 5322。message_factory
属性的默认值是EmailMessage
。除了上面列出的适用于所有策略的可设置属性之外,此策略还添加了以下附加属性
在 3.6 版本中添加: [1]
- utf8¶
如果为
False
,则遵循 RFC 5322,通过将非 ASCII 字符编码为“编码字”来支持它们。如果为True
,则遵循 RFC 6532,并对标头使用utf-8
编码。以这种方式格式化的消息可能会传递给支持SMTPUTF8
扩展的 SMTP 服务器 (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
对象会调用此对象的相应方法,并将其作为第一个参数传递给消息对象,并将传递给它的任何参数或关键字作为附加参数。默认情况下,content_manager
设置为raw_data_manager
。在 3.4 版本中添加。
该类提供了
Policy
的抽象方法的以下具体实现- header_source_parse(sourcelines)¶
名称被解析为直到“
:
”的所有内容,并按原样返回。该值通过剥离第一行的开头空格、将所有后续行连接在一起并剥离任何尾随回车符或换行符来确定。
- header_store_parse(name, value)¶
名称保持不变地返回。如果输入值具有
name
属性并且它与 name (忽略大小写)匹配,则该值保持不变地返回。否则,会将 name 和 value 传递给header_factory
,并将生成的标头对象作为值返回。在这种情况下,如果输入值包含 CR 或 LF 字符,则会引发ValueError
。
- header_fetch_parse(name, value)¶
如果值具有
name
属性,则将其原样返回。否则,将删除任何 CR 或 LF 字符的 _name_ 和 _value_ 传递给header_factory
,并返回生成的标头对象。任何被代理转义的字节都会转换为 Unicode 的未知字符字形。
- fold(name, value)¶
标头折叠由
refold_source
策略设置控制。如果值不具有name
属性,则认为它是“源值”(具有name
属性意味着它某种形式的标头对象)。如果根据策略需要重新折叠源值,则通过将删除任何 CR 和 LF 字符的 _name_ 和 _value_ 传递给header_factory
将其转换为标头对象。标头对象的折叠是通过使用当前策略调用其fold
方法来完成的。使用
splitlines()
将源值拆分为多行。如果该值不重新折叠,则使用策略中的linesep
重新连接这些行并返回。例外情况是包含非 ASCII 二进制数据的行。在这种情况下,无论refold_source
设置如何,该值都会被重新折叠,这会导致使用unknown-8bit
字符集对二进制数据进行 CTE 编码。
以下 EmailPolicy
实例提供了适用于特定应用领域的默认值。请注意,在将来,这些实例(特别是 HTTP
实例)的行为可能会被调整,以更加符合与其领域相关的 RFC。
- email.policy.default¶
所有默认值均未更改的
EmailPolicy
实例。此策略使用标准的 Python\n
行尾符,而不是 RFC 正确的\r\n
。
- email.policy.SMTP¶
适用于根据电子邮件 RFC 序列化消息。与
default
类似,但linesep
设置为符合 RFC 的\r\n
。
- email.policy.SMTPUTF8¶
与
SMTP
相同,只是utf8
为True
。在不使用标头中的编码词的情况下序列化消息到消息存储很有用。仅当发件人或收件人地址包含非 ASCII 字符时,才应将其用于 SMTP 传输(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 从 Python 3.2 API 更改为以下方式
在
Message
上设置标头会导致解析该标头并创建标头对象。从
Message
获取标头值会导致解析该标头并创建并返回标头对象。任何标头对象或由于策略设置而重新折叠的任何标头都使用完全实现 RFC 折叠算法的算法进行折叠,包括知道在何处需要和允许编码词。
从应用程序视图来看,这意味着通过 EmailMessage
获得的任何标头都是具有额外属性的标头对象,其字符串值是标头的完全解码的 Unicode 值。同样,可以使用 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)¶
名称和值原样返回。
脚注