email.generator:生成 MIME 文档

源代码: Lib/email/generator.py


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

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

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

为了适应对 SMIME 签名消息的可重复处理,Generator 禁用 multipart/signed 类型和所有子部分的消息部分的标头折叠。

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

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

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

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

如果指定了 policy,则使用该策略来控制消息生成。如果 policyNone(默认值),则使用与传递给 flattenMessageEmailMessage 对象关联的策略来控制消息生成。有关 policy 控制的详细信息,请参阅 email.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 的任何正文部分的非 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_ 默认为 policymangle_from_ 设置的值(对于 compat32 策略为 True,对于所有其他策略为 False)。mangle_from_ 旨在用于消息以 Unix mbox 格式存储时(请参阅 mailbox为什么内容长度格式是错误的)。

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

如果指定了 policy,则使用该策略来控制消息生成。如果 policyNone(默认值),则使用与传递给 flattenMessageEmailMessage 对象关联的策略来控制消息生成。有关 policy 控制的详细信息,请参阅 email.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 基类相同。

脚注