email.policy策略对象

版本3.3.

新增源代码: Lib / email / policy.py


email包的主要关注的是处理各种电子邮件和MIME RFC所描述的电子邮件消息。但是,电子邮件消息的一般格式(一个标题字段块,每个字段包含一个名称后跟一个冒号后跟一个值,整个块后跟一个空行和一个’body’),是一种在电子邮件的境界。其中一些用途与主要的电子邮件RFC非常接近,有些则没有。即使在处理电子邮件时,有时也需要严格遵守RFC,例如生成与不符合标准的电子邮件服务器互操作的电子邮件,或者以违反标准的方式实施要使用的扩展.

策略对象使电子邮件包能够灵活处理所有已分离的用例.

A Policyobject封装了一组属性和方法,用于在使用期间控制电子邮件包的各个组件的行为.Policy实例可以传递给电子邮件包中的各种类和方法以更改默认行为。可设置的值及其默认值如下所述.

电子邮件包中的所有类都使用默认策略。对于所有parser类和相关的便利函数,以及Message类,这是Compat32策略,通过其相应的预定义实例compat32。此策略提供与电子邮件包的Python3.3之前版本的完全向后兼容性(在某些情况下,包括执行兼容性).

policy关键字的默认值为EmailMessageEmailPolicy策略,通过预定义的实例default.

当创建一个MessageEmailMessage对象时,它获取一个策略。如果消息是由parser,传递给解析器的策略将是它创建的消息使用的策略。如果消息是由程序创建的,则可以在创建策略时指定策略。当邮件传递给generator,生成器默认使用消息中的策略,但您也可以将特定策略传递给生成器,该策略将覆盖存储在消息对象上的策略.

的默认值policy的关键字email.parser类和解析器的便利功能会改变在未来的Python版本中。所以你应该在调用 module.parser中描述的任何类和函数时,总是明确指定要使用的策略

本文档的第一部分介绍了Policy抽象基类的功能,它定义了所有策略对象共有的功能,包括compat32。这包括由电子邮件包在内部调用的某些hook方法,自定义策略可以覆盖这些方法以获取不同的行为。第二部分描述了混凝土类EmailPolicyCompat32,它们分别实现了提供标准行为和向后兼容行为和特征的钩子.

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纠正线创建二进制字符串以输入sendmail"s stdin时的分隔符,默认策略将使用\n lineseparators.

一些电子邮件包方法接受policy关键字参数,允许为该方法覆盖策略。例如,下面的代码使用上一个示例中as_bytes()对象msg方法,并使用运行它的平台的本机lineseparator将消息写入文件:

>>> import os>>> with open("converted.txt", "wb") as f:...     f.write(msg.as_bytes(policy=msg.policy.clone(linesep=os.linesep)))17

策略对象也可以使用加法运算符进行组合,生成apolicy对象,其设置是对象的非默认值的组合:

>>> 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_length80>>> apolicy = policy80 + policy100>>> apolicy.max_line_length100
class email.policy.Policy**kw

对于所有策略类,这是抽象基类。它提供了几个简单方法的默认实现,以及不变性属性的实现,clone()方法和构造函数语义.

策略类的构造函数可以传递各种关键字参数。可以指定的参数是此类的任何非方法属性,以及具体类上的任何其他非方法属性。构造函数中指定的Avalue将覆盖相应属性的默认值.

此类定义以下属性,因此可以在任何策略类的构造函数中传递以下值:

max_line_length

序列化输出中任何行的最大长度,不包括行尾字符。默认值为78,每 RFC 5322 。值0None表示根本没有换行.

linesep

用于终止序列化输出中的行的字符串。默认是\n因为这是Python使用的内部行尾规则,但RFC需要\r\n

cte_type

控制可能或将要使用的内容传输编码的类型。可能的值是:

7bit 所有数据必须是“7位清洁”(仅限ASCII)。这意味着必要的数据将使用quoted-printable或base64编码进行编码.
8bit data不限于7位清理。标题中的数据必须仅为ASCII,因此将被编码(参见fold_binary()utf8下面的forexceptions),但是正文部分可能会使用8bit CTE.

cte_type 8bit的值仅适用于BytesGenerator,而不是Generator,因为字符串不能包含二进制数据。如果Generator在指定cte_type=8bit的策略下运行,它将表现为cte_type7bit.

raise_on_defect

如果True,任何缺陷遇到的将被视为错误。如果False(默认值),缺陷将传递给register_defect()方法

mangle_from_

如果True,以“From “开头的行通过在他们面前放一个>来装饰身体。当生成器序列化消息时使用此参数。默认:False.

版本3.5中新增: mangle_from_参数

message_factory

用于构造新的空消息对象的工厂函数。在构建消息时由解析器使用。默认为None,在这种情况下Message使用.

新版本3.6.

以下Policy方法是使用电子邮件库通过代码调用以使用自定义设置创建策略实例:

clone**kw

返回一个新的Policy实例,其属性具有相同的值当前实例,除非这些属性通过关键字arguments赋予新值.

剩余的Policy方法由电子邮件包代码调用,并不打算由使用的应用程序调用电子邮件包。自定义策略必须实现所有这些方法.

handle_defect(obj, defect)

处理defect发现在obj。当电子邮件包调用thismethod时,defect将始终是Defect.

的子类。默认实现检查raise_on_defect标志。如果是True, defect被提出作为例外。如果是False(默认),objdefect传递给register_defect().

register_defectobj, defect

defect上注册一个obj。在电子邮件包中,defect将永远是Defect.

的子类。默认实现调用append defects属性的obj方法。当电子邮件包调用handle_defect,obj时通常会有defects具有append方法的属性。与电子邮件包一起使用的自定义对象类型(例如,自定义Message对象)也应该提供这样的属性,否则解析的消息中的缺陷会引起意外错误.

header_max_countname

返回名为name.

标题添加到EmailMessageMessage对象时调用。如果返回的值不是0None,并且已经有多个头文件名为name大于或等于返回的值,ValueError被提升.

因为Message.__setitem__是将值附加到标题列表,很容易创建重复标题而不实现它。这种方法允许某些标题被限制在该标题的实例数量中,可以添加到Message编程。(解析器没有观察到这个限制,它将忠实地生成解析的消息中存在的多个头。)

默认实现返回None所有标题名称.

header_source_parse (sourcelines )

电子邮件包使用字符串列表调用此方法,每个字符串都使用在被解析的源中找到的行分隔字符。第一行包括字段标题名称和分隔符。源中的所有空格都被保留。该方法应该返回(name, value)将要存储在Message中的元组来表示已解析的标题.

如果实现希望保持与现有邮件包策略的兼容性,name应该是案例保留的名称(所有字符直到’:‘分隔符),而value应该是展开的值(删除所有行分隔符,但空格键完整),去掉前导空格.

sourcelines可能包含代理二进制数据.

没有默认实现

header_store_parsename, value

当应用程序修改Message以编程方式(而不是由aparser创建的Message)。该方法应返回(name, value)元组,该元组将存储在Message中以表示标题.

如果实现希望保持与现有邮件包策略的兼容性,则namevalue应该是字符串orstring子类,不会改变传递的参数的内容.

没有默认的实现

header_fetch_parsename, value

电子邮件包调用此方法时,namevalue目前存放在Message当应用程序请求该标头时,无论方法返回什么,都将作为要检索的标头的值传回给应用程序。请注意,中可能存在多个具有相同名称的标头Message;该方法传递了指向要返回给应用程序的头的特定名称和值.

value可能包含代理二进制数据。方法返回的值应该有nosurrogateescaped二进制数据.

没有默认实现

foldname, value

电子邮件包调用此方法时,namevalue目前存放在Message对于给定的标题。该方法应该通过将namevalue组合并插入linesep在适当的地方的字符。请参阅 RFC 5322 讨论折叠电子邮件标题的规则.

value可能包含代理二进制数据。在方法返回的字符串中应该有nosurrogateescaped二进制数据.

fold_binary (name, value

fold(),除了返回的值应该是abytes对象而不是字符串.

value可能包含代理二进制数据。这些可以转换回返回的字节对象中的二进制数据.

class email.policy.EmailPolicy (**kw)

这个具体的Policy提供旨在完全符合当前电子邮件RFC的行为。这些包括(但不限于) RFC 5322 , RFC 2047 ,以及当前的MIME RFCs.

此策略添加了新的头解析和折叠算法。而不是简单的字符串,标题是str具有依赖于字段类型的属性的子类。解析和折叠算法完全实现 RFC 2047 RFC 5322 .

message_factoryattribute是EmailMessage.

除了上面列出的适用于allpolicies的可设置属性之外,此策略还添加了以下附加属性:

版本3.6中新增: [1]

utf8

如果False,按照 RFC 5322 ,通过将它们编码为“编码的单词”来支持非ASCII字符。如果True,请按照 RFC 6532 并使用utf-8编码标题。以这种方式格式化的消息可以传递给支持SMTPUTF8扩展的SMTP服务器( RFC 6531 ).

refold_source

如果是Message对象起源于parser(与程序设置相反),thisattribute指示生成器在将消息转换回序列化形式时是否应该重新折叠该值。可能的值是:

none 所有源值都使用原始折叠
long 有任何超过max_line_length的行的源值将被重新折叠
all 所有值都是refoldded .

默认是long.

header_factory

一个可调用的,有两个参数,namevalue,其中name是头字段名称,value是展开的头字段值,并返回表示该头的字符串子类。Adefault header_factory(见headerregistry)提供支持自定义解析各种地址和日期 RFC 5322 标头字段类型和主要MIME标头字段stypes。将来会添加支持有条件的自定义解析.

content_manager

具有至少两个方法的对象:get_content和set_content。get_content()set_content() EmailMessage调用对象,它调用此对象的相应方法,将消息对象作为其第一个参数传递给它,并将任何传递给它的参数或关键字作为附加参数传递给它。默认情况下 content_manager被设置为raw_data_manager.

版本3.4.

该类提供了Policy

header_max_countname

返回max_count用于表示具有给定名称的标题的专用类的属性.

header_source_parse(sourcelines)

该名称被解析为“:”并返回修改后的所有内容。通过从第一行的剩余部分剥离前导空格,将所有后续行连接在一起,并剥离任何尾随回车符或换行符来确定该值.

header_store_parse (name, value

名称未更改。如果输入值具有name属性且匹配name忽略大小写,则返回值。否则将namevalue传递给header_factory,并将结果头对象作为值返回。在这种情况下,如果输入值包含CR或LF字符,则会引发ValueError.

header_fetch_parse(name, value)

如果值为name属性,它返回到未修改。否则namevalue与任何CR或LF字符被删除,传递给header_factory,并且resultheader对象是回。任何代理字节转换为unicode unknown-character glyph.

fold (name, value)

头部折叠由refold_source策略设置。如果和,则值被视为“源值”只有它没有name属性(具有name属性意味着它是某种类型的头对象)。如果需要根据策略重新链接源值,则会将其转换为绕过name并且value将任何CR和LF字符移除到header_factory。通过使用当前策略调用其fold方法来完成对标题对象的折叠.

使用splitlines()将源值拆分为行。如果不重新折叠该值,则使用linesep从政策和返回。例外是包含非ascii二进制数据的行。在这种情况下,重新折叠值,无论refold_source设置,导致二进制数据使用unknown-8bit charset.

fold_binary(name, value)

进行CTE编码。与fold()相同cte_type7bit,除了返回的值是bytes.

如果cte_type8bit,非ASCII二进制数据被转换回字节。无论refold_header设置,因为无法知道二进制数据是由单字节字符还是多字节字符组成.

以下EmailPolicy提供适用于特定应用程序域的默认值。注意以后这些实例的行为(特别是HTTP实例)可以进行调整,以便更紧密地符合与其域相关的RFC .

email.policy.default

一个EmailPolicy的实例,所有默认值都保持不变。此策略使用标准Python \n行结尾而不是RFC纠正\r\n.

email.policy.SMTP

适合按照电子邮件RFCs.Like default序列化邮件,但是linesep设置为\r\n,这是RFCcompliant。

email.policy.SMTPUTF8

SMTP除了utf8True。用于将消息序列化到消息存储库而不使用标头中的编码字。如果这些地址或收件人地址具有非ASCII字符(smtplib.SMTP.send_message()方法自动处理),则只能用于SMTP传输.

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获取标题值导致正在解析的标题和标题对象创造和回复.
  • 任何头对象或由于策略设置而重新折叠的任何头都使用完全实现RF折叠算法的算法折叠,包括知道需要和允许编码字的位置.

从应用程序视图,这意味着通过EmailMessage获得的任何头是带有extraattributes的头对象,其字符串值是头的完全解码的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_parsesourcelines

的抽象方法的以下具体实现。该名称被解析为一切’:‘并返回修改。通过从第一行的剩余部分剥离前导空格,将所有后续行连接在一起,并剥离任何尾随回车符或换行符来确定该值.

header_store_parse (name, value

名称和值未经修改返回.

header_fetch_parse (name, value)

如果值包含二进制数据,则将其转换为Header对象使用unknown-8bit charset.Otherwise它未经修改地返回.

fold (name, value)

使用Headerfoldalgorithm,它保留值中的现有换行符,并将结果行包装到max_line_length。非ASCII二进制数据是使用unknown-8bit charset进行CT编码的

fold_binary/name, value/

//使用Header折叠算法折叠头部,它保留了值中现有的换行符,并将结果行包装到max_line_length。如果cte_type7bit,则使用unknown-8bit字符集对非ascii二进制数据进行CTE编码。否则使用原始源头,其现有的行中断和它可能包含的任何(RFC无效)二进制数据.

email.policy.compat32

Compat32的实例,提供与电子邮件包的行为的向后兼容性Python 3.2.

Footnotes

[1] 在3.3中作为临时特征添加了.

评论被关闭。