19.1.4. email.policy
:Policy Objects ¶
版本3.3中的新功能。
email
包的首要关注点是处理电子邮件,如各种电子邮件和MIME RFC所述。然而,电子邮件消息的一般格式(每个标题字段的块由名称后跟冒号后跟一个值,整个块后跟空白行和任意“主体”)的格式是已经找到的格式实用程序在电子邮件领域之外。这些用途中的一些与主要RFC相当相近,一些不使用。即使使用电子邮件,有时也需要严格遵守RFC。
策略对象为电子邮件包提供了处理所有这些不同用例的灵活性。
Policy
对象封装了一组属性和方法,用于控制电子邮件包在使用过程中各种组件的行为。Policy
实例可以传递到电子邮件包中的各种类和方法,以更改默认行为。可设置的值及其默认值如下所述。
电子邮件包中的所有类都使用默认策略。此策略名为Compat32
,具有对应的预定义实例名为compat32
。它提供与Python3.3版本的电子邮件包完全向后兼容(在某些情况下,包括错误兼容性)。
本文档的第一部分介绍了Policy
的功能,abstract base class,定义了所有策略对象共有的功能,包括compat32
这包括由电子邮件包内部调用的某些挂接方法,自定义策略可以覆盖以获取不同的行为。
当创建Message
对象时,它会获取策略。默认情况下,这将是compat32
,但可以指定不同的策略。如果Message
是由parser
创建的,则传递给解析器的策略将是它创建的Message
使用的策略。如果程序创建了Message
,则可以在创建策略时指定策略。当Message
传递到generator
时,生成器默认使用Message
中的策略,但您也可以传递特定策略生成器将覆盖存储在Message
对象上的。
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
在创建二进制字符串时使用RFC正确的行分隔字符,以便将sendmail's
stdin
使用\n
行分隔符。
一些电子邮件包方法接受策略关键字参数,允许为该方法覆盖策略。例如,以下代码使用上一个示例中的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
还可以使用添加操作符号组合策略对象,生成策略对象,其设置是总计对象的非默认值的组合:
>>> 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。它提供了几个平凡方法的默认实现,以及immutability属性,
clone()
方法和构造函数语义的实现。策略类的构造函数可以传递各种关键字参数。可以指定的参数是此类上的任何非方法属性,以及具体类上的任何其他非方法属性。在构造函数中指定的值将覆盖相应属性的默认值。
此类定义以下属性,因此以下值可以在任何策略类的构造函数中传递:
-
linesep
¶ 用于终止序列化输出中的行的字符串。默认值为
\n
,因为这是Python使用的内部结束规则,虽然RFC需要\r\n
。
-
cte_type
¶ 控制可能需要或需要使用的内容传输编码的类型。可能的值为:
7bit
所有数据必须是“7位清除”(仅限ASCII)。这意味着在必要的数据将使用quoted-printable或base64编码进行编码。 8bit
数据不被约束为7位清洁。头部中的数据仍然需要是仅ASCII,因此将被编码(见下面的'binary_fold'异常),但身体部分可以使用 8bit
CTE。8bit
的cte_type
值仅适用于BytesGenerator
,而不适用于Generator
,因为字符串不能包含二进制数据。如果Generator
在指定cte_type=8bit
的策略下运行,则它将表现为cte_type
为7bit
-
raise_on_defect
¶ 如果
True
,则遇到的任何缺陷都将作为错误提出。如果False
(默认值),缺陷将传递到register_defect()
方法。
以下
Policy
方法旨在由代码调用,使用电子邮件库使用自定义设置创建策略实例:剩余的
Policy
方法由电子邮件包代码调用,并且不打算由使用电子邮件包的应用程序调用。自定义策略必须实现所有这些方法。-
handle_defect
(obj, defect)¶ 处理obj上发现的缺陷。当电子邮件包调用此方法时,defect将始终是
Defect
的子类。默认实现检查
raise_on_defect
标志。如果它True
,则作为异常引发缺陷。如果是False
(默认值),则将obj和缺陷传递给register_defect()
。
-
register_defect
(obj, defect)¶ 在obj上注册缺陷。在电子邮件包中,defect将始终是
Defect
的子类。默认实现调用obj的
defects
属性的append
方法。当电子邮件包调用handle_defect
时,obj通常会有一个具有append
方法的defects
属性。与电子邮件包一起使用的自定义对象类型(例如,自定义Message
对象)也应提供此类属性,否则解析的邮件中的缺陷将引发意外错误。
-
header_max_count
(name)¶ 返回名为name的最大允许头数。
当标头添加到
Message
对象时调用。如果返回值不是0
或None
,并且已有一些名为name的头等于返回的值,则ValueError
。因为
Message.__setitem__
的默认行为是将值附加到标题列表,所以很容易创建重复的标题而不意识到它。此方法允许某些头部在可以以编程方式添加到Message
的头部实例数量上受到限制。(解析器不会观察到该限制,这将忠实地产生与解析的消息中存在的标头一样多的头)。默认实现为所有标题名返回
None
。
-
header_source_parse
(sourcelines)¶ 电子邮件包使用字符串列表调用此方法,每个字符串以在要解析的源中找到的行间隔字符结尾。第一行包括字段头名称和分隔符。源中的所有空格都保留。该方法应该返回要存储在
Message
中的(名称, 值) 解析头。
如果实施希望保留与现有电子邮件包策略的兼容性,则名称应为大小写保留的名称(所有字符直到“
:
”分隔符),而 value应该是展开的值(删除所有行分隔符,但空白保持不变),删除前导空白。源线可能包含代理转义的二进制数据。
没有默认实现
-
header_store_parse
(name, value)¶ 当应用程序以编程方式修改
Message
(与解析器创建的Message
相反)时,电子邮件包使用应用程序提供的名称和值调用此方法。 。该方法应该返回要存储在Message
中的(名称, 值) 标题。
如果实现希望保留与现有电子邮件包策略的兼容性,则名称和值应为不更改传递的参数的内容的字符串或字符串子类。
没有默认实现
-
header_fetch_parse
(name, value)¶ 当应用程序请求该标题时,电子邮件包使用当前存储在
Message
中的名称和值调用此方法,方法返回是作为要检索的头的值传递回应用程序的内容。请注意,在Message
中可能存在多个具有相同名称的标头;该方法将传递要返回给应用程序的头的特定名称和值。值可能包含代理转义的二进制数据。在方法返回的值中不应有替代转义的二进制数据。
没有默认实现
-
- 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)¶ 将不更改返回名称和值。
-
提供Compat32
的实例作为模块常数:
注意
以下文档介绍了provisional basis中包含在标准库中的新策略。如果核心开发人员认为有必要,可能会发生向后不兼容的更改(直到并包括删除该功能部件)。
- class
email.policy.
EmailPolicy
(**kw)¶ 此具体的
Policy
提供了旨在完全符合当前电子邮件RFC的行为。这些包括(但不限于) RFC 5322, RFC 2047和当前MIME RFC。此策略添加新的标头解析和折叠算法。取代简单字符串,标头是
str
子类,其属性取决于字段的类型。解析和折叠算法完全实现 RFC 2047和 RFC 5322。除了上面列出的适用于所有策略的可设置属性之外,此策略还添加了以下附加属性:
-
utf8
¶ 如果
False
,请按照 RFC 5322,通过将其编码为“编码字词”来支持标头中的非ASCII字符。如果True
,请按照 RFC 6532并使用utf-8
以此方式格式化的邮件可传递到支持SMTPUTF8
扩展名( RFC 6531)的SMTP服务器。
-
refold_source
¶ 如果
Message
对象中的头部值来源于parser
(与程序设置相反),则此属性指示生成器是否应重新折叠该值在将消息转换回流形式时。可能的值为:none
所有源值使用原始折叠 long
具有任何长于 max_line_length
的行的源值将被重新折叠all
所有值都重新折叠。 默认值为
long
。
-
header_factory
¶ 具有
name
和value
两个参数的可调用项,其中name
是头字段名称,value
是展开的头字段值,并返回表示该头的字符串子类。提供了理解一些 RFC 5322头字段类型的默认header_factory
(请参阅headerregistry
)。(目前地址字段和日期字段有特殊处理,而所有其他字段被视为非结构化。此列表将在扩展程序标记为稳定之前完成。)
-
content_manager
¶ 具有至少两个方法的对象:get_content和set_content。当调用
Message
对象的get_content()
或set_content()
方法时,将调用此对象的相应方法,消息对象作为其第一个参数,以及作为附加参数传递给它的任何参数或关键字。默认情况下,content_manager
设置为raw_data_manager
。版本3.4中的新功能。
该类提供了
Policy
的抽象方法的以下具体实现:-
header_store_parse
(name, value)¶ 名称将保持不变。如果输入值具有
name
属性,并且它匹配名称忽略大小写,则返回值不变。否则,将名称和值传递到header_factory
,并将返回的结果标题对象作为值。在这种情况下,如果输入值包含CR或LF字符,则会引发ValueError
。
-
header_fetch_parse
(name, value)¶ 如果值具有
name
属性,则返回未修改。否则,将除去了任何CR或LF字符的名称和值传递到header_factory
,并返回生成的标题对象。任何代理转义的字节变成unicode未知字符字形。
-
fold
(name, value)¶ 标题折叠由
refold_source
策略设置控制。当且仅当它没有name
属性(具有name
属性意味着它是某种类型的头对象)时,该值被认为是“源值” )。如果源值需要根据策略重新折叠,则通过将除去了任何CR和LF字符的名称和值传递给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
设置为\r\n
,这是RFC兼容。
-
email.policy.
SMTPUTF8
¶ 与
SMTP
相同,但utf8
为True
。用于将消息序列化到消息存储,而不在标头中使用编码字。如果发件人或收件人地址具有非ASCII字符(smtplib.SMTP.send_message()
方法自动处理此字符),则应仅用于SMTP传输。
-
email.policy.
HTTP
¶ 适用于串行化标头以用于HTTP流量。像
SMTP
除了max_line_length
设置为None
(无限制)。
-
email.policy.
strict
¶ 方便实例。除了
raise_on_defect
设置为True
,与default
相同。这允许任何政策通过写作严格:somepolicy + policy.strict
对于所有这些EmailPolicies
,电子邮件包的有效API从Python 3.2 API以以下方式更改:
- Setting a header on a
Message
results in that header being parsed and a header object created.- Fetching a header value from a
Message
results in that header being parsed and a header object created and returned.- Any header object, or any header that is refolded due to the policy settings, is folded using an algorithm that fully implements the RFC folding algorithms, including knowing where encoded words are required and allowed.
从应用程序视图,这意味着通过Message
获得的任何头都是具有额外属性的头对象,其字符串值是头的完全解码的unicode值。同样,可以使用unicode字符串为报头分配新值或创建新报头,并且策略将负责将unicode字符串转换为正确的RFC编码形式。
头对象及其属性在headerregistry
中描述。