email.generator:生成 MIME 文档

源代码: Lib/email/generator.py


最常见的任务之一是生成由邮件对象结构表示的电子邮件的扁平(序列化)版本。如果你想通过 smtplib.SMTP.sendmail()nntplib 模块发送邮件,或者在控制台上打印邮件,则需要执行此操作。生成器类的作用是获取邮件对象结构并生成序列化表示。

email.parser 模块一样,你不限于捆绑生成器的功能;你可以自己从头开始编写一个。但是,捆绑生成器知道如何以符合标准的方式生成大多数电子邮件,应该可以很好地处理 MIME 和非 MIME 电子邮件,并且设计为字节导向的解析和生成操作是逆操作,假设对两者都使用了相同的非转换 policy。也就是说,通过 BytesParser 类解析序列化的字节流,然后使用 BytesGenerator 重新生成序列化的字节流,应该生成与输入完全相同的输出[1]。(另一方面,对程序构建的 EmailMessage 使用生成器可能会更改 EmailMessage 对象,因为默认值已填入。)

可以使用 Generator 类将邮件展平为文本(而不是二进制)序列化表示形式,但由于 Unicode 无法直接表示二进制数据,因此必须将邮件转换为仅包含 ASCII 字符的内容,使用标准电子邮件 RFC 内容传输编码技术对电子邮件进行编码,以便通过“8 位干净”的通道进行传输。

为了适应 SMIME 签名邮件的可重现处理,Generator 禁用类型为 multipart/signed 和所有子部分的邮件部分的头折叠。

class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)

返回一个 BytesGenerator 对象,该对象会将提供给 flatten() 方法的任何邮件,或提供给 write() 方法的任何代理转义编码文本,写入到 类文件对象 outfpoutfp 必须支持接受二进制数据的 write 方法。

如果可选的 mangle_from_True,则在正文中以 "From " 开头的任何行前面放置 > 字符,即行开头为 From 后跟一个空格。mangle_from_ 默认为 mangle_from_ 设置的 policy 值(对于 compat32 策略为 True,对于其他所有策略为 False)。mangle_from_ 旨在在以 Unix mbox 格式存储邮件时使用(请参阅 mailbox内容长度格式为何糟糕)。

如果 maxheaderlen 不为 None,则重新折叠任何长度超过 maxheaderlen 的标头行,或者如果 0,则不重新包装任何标头。如果 manheaderlenNone(默认值),则根据 policy 设置包装标头和其他邮件行。

如果指定了 policy,则使用该策略来控制邮件生成。如果 policyNone(默认值),则使用与 MessageEmailMessage 对象(传递给 flatten 以控制邮件生成)关联的策略。请参阅 email.policy 了解 policy 控制的详细信息。

在 3.2 版中添加。

在 3.3 版中更改:添加了 policy 关键字。

在 3.6 版中更改:mangle_from_maxheaderlen 参数的默认行为是遵循策略。

flatten(msg, unixfrom=False, linesep=None)

将以 msg 为根的邮件对象结构的文本表示形式打印到在创建 BytesGenerator 实例时指定的输出文件中。

如果 policy 选项 cte_type8bit(默认值),则复制原始解析邮件中未修改的任何标头到输出,其中任何设置了高位的字节都与原始标头中的一样,并保留任何正文部分的非 ASCII Content-Transfer-Encoding。如果 cte_type7bit,则根据需要使用 ASCII 兼容的 Content-Transfer-Encoding 转换设置了高位的字节。也就是说,将具有非 ASCII Content-Transfer-EncodingContent-Transfer-Encoding: 8bit)的部分转换为 ASCII 兼容的 Content-Transfer-Encoding,并使用 MIME unknown-8bit 字符集对标头中 RFC 无效的非 ASCII 字节进行编码,从而使它们符合 RFC。

如果 unixfromTrue,则在根邮件对象的 RFC 5322 标头之前打印 Unix 邮箱格式使用的信封标头分隔符(请参阅 mailbox)。如果根对象没有信封标头,则构建一个标准信封标头。默认值为 False。请注意,对于子部分,永远不会打印信封标头。

如果 linesep 不为 None,则将其用作扁平化邮件的所有行之间的分隔符。如果 linesepNone(默认值),则使用 policy 中指定的值。

clone(fp)

返回此 BytesGenerator 实例的独立克隆,具有完全相同的选项设置,并将 fp 作为新的 outfp

write(s)

使用 ASCII 编解码器和 surrogateescape 错误处理程序对 s 进行编码,并将其传递给传递给 BytesGenerator 的构造函数的 outfpwrite 方法。

为了方便,EmailMessage 提供了方法 as_bytes()bytes(aMessage)(又名 __bytes__()),这些方法简化了生成消息对象的序列化二进制表示的过程。有关更多详细信息,请参阅 email.message

由于字符串无法表示二进制数据,因此 Generator 类必须将其展平的任何消息中的任何二进制数据转换为 ASCII 兼容格式,方法是将其转换为 ASCII 兼容的 Content-Transfer_Encoding。使用电子邮件 RFC 的术语,你可以将此视为 Generator 序列化到并非“8 位干净”的 I/O 流。换句话说,大多数应用程序都希望使用 BytesGenerator,而不是 Generator

class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)

返回一个 Generator 对象,它会将提供给 flatten() 方法的任何消息,或提供给 write() 方法的任何文本写入 类文件对象 outfpoutfp 必须支持接受字符串数据的 write 方法。

如果可选的 mangle_from_True,则在正文中以 "From " 开头的任何行前面放置 > 字符,即行开头为 From 后跟一个空格。mangle_from_ 默认为 mangle_from_ 设置的 policy 值(对于 compat32 策略为 True,对于其他所有策略为 False)。mangle_from_ 旨在在以 Unix mbox 格式存储邮件时使用(请参阅 mailbox内容长度格式为何糟糕)。

如果 maxheaderlen 不为 None,则重新折叠任何长度超过 maxheaderlen 的标头行,或者如果 0,则不重新包装任何标头。如果 manheaderlenNone(默认值),则根据 policy 设置包装标头和其他邮件行。

如果指定了 policy,则使用该策略来控制邮件生成。如果 policyNone(默认值),则使用与 MessageEmailMessage 对象(传递给 flatten 以控制邮件生成)关联的策略。请参阅 email.policy 了解 policy 控制的详细信息。

在 3.3 版中更改:添加了 policy 关键字。

在 3.6 版中更改:mangle_from_maxheaderlen 参数的默认行为是遵循策略。

flatten(msg, unixfrom=False, linesep=None)

将根为 msg 的消息对象结构的文本表示形式打印到在创建 Generator 实例时指定的输出文件中。

如果 policy 选项 cte_type8bit,则生成消息,就像该选项被设置为 7bit 一样。(这是必需的,因为字符串无法表示非 ASCII 字节。)根据需要,使用 ASCII 兼容的 Content-Transfer-Encoding 转换任何设置了高位的字节。也就是说,将具有非 ASCII Content-Transfer-EncodingContent-Transfer-Encoding: 8bit)的部分转换为 ASCII 兼容的 Content-Transfer-Encoding,并使用 MIME unknown-8bit 字符集对头中的 RFC 无效的非 ASCII 字节进行编码,从而使其符合 RFC。

如果 unixfromTrue,则在根消息对象的 RFC 5322 头的第一个头之前打印 Unix 邮箱格式使用的信封头分隔符(请参阅 mailbox)。如果根对象没有信封头,则创建一个标准信封头。默认值为 False。请注意,对于子部分,永远不会打印信封头。

如果 linesep 不为 None,则将其用作扁平化邮件的所有行之间的分隔符。如果 linesepNone(默认值),则使用 policy 中指定的值。

3.2 版中已更改: 添加了对重新编码 8bit 消息正文和 linesep 参数的支持。

clone(fp)

返回此 Generator 实例的独立克隆,其具有完全相同的选项,并且 fp 作为新的 outfp

write(s)

s 写入传递给 Generator 构造函数的 outfpwrite 方法。这仅为 Generator 实例提供了足够的文件式 API,以便在 print() 函数中使用。

为了方便起见,EmailMessage 提供了方法 as_string()str(aMessage)(又名 __str__()),这些方法简化了消息对象的格式化字符串表示形式的生成。有关更多详细信息,请参阅 email.message

email.generator 模块还提供了一个派生类 DecodedGenerator,它类似于 Generator 基类,但不同之处在于非 text 部分不会序列化,而是用填充有关于该部分的信息的模板派生的字符串在输出流中表示。

class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)

行为类似于 Generator,但对于传递给 Generator.flatten() 的消息的任何子部分,如果子部分的主类型为 text,则打印子部分的解码有效负载,如果主类型不是 text,则不打印它,而是使用来自该部分的信息填写字符串 fmt,并打印填充后的字符串。

要填写 fmt,请执行 fmt % part_info,其中 part_info 是由以下键和值组成的字典

  • type – 非 text 部分的完整 MIME 类型

  • maintype – 非 text 部分的主 MIME 类型

  • subtype – 非 text 部分的子 MIME 类型

  • filename – 非 text 部分的文件名

  • description – 与非 text 部分关联的描述

  • encoding – 非 text 部分的内容传输编码

如果 fmtNone,则使用以下默认 fmt

“[消息中省略的非文本 (%(type)s) 部分,文件名 %(filename)s]”

可选的 _mangle_from_maxheaderlenGenerator 基类相同。

脚注