"email.generator": Generating MIME documents
********************************************

**源代码:** Lib/email/generator.py

======================================================================

One of the most common tasks is to generate the flat (serialized)
version of the email message represented by a message object
structure.  You will need to do this if you want to send your message
via "smtplib.SMTP.sendmail()" or the "nntplib" module, or print the
message on the console.  Taking a message object structure and
producing a serialized representation is the job of the generator
classes.

与 "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()" 方法的任何经过代理转义编码的文本写入到
   *file-like object* *outfp*。 *outfp* 必须支持接受二进制数据的
   "write" 方法。

   如果可选的 *mangle_from_* 为 "True"，则会将一个 ">" 字符放到消息体
   中恰好以字符串 ""From "" 打头，即开头文本为 "From" 加一个空格的任何
   行的前面。 *mangle_from_* 默认为 *policy* 的 "mangle_from_" 设置值
   (对于 "compat32" 策略为 "True" 而对于所有其他策略则为 "False")。
   *mangle_from_* 被设计为在当消息以 Unix mbox 格式存储时使用 (参见
   "mailbox" 和 WHY THE CONTENT-LENGTH FORMAT IS BAD)。

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

   如果指定了 *policy*，则使用该策略来控制消息的生成。 如果 *policy*
   为 "None" (默认值)，则使用与传递给 "flatten" 的 "Message" 或
   "EmailMessage" 对象相关联的策略来控制消息的生成。 请参阅
   "email.policy" 了解有关 *policy* 所控制内容的详情。

   Added in version 3.2.

   在 3.3 版本发生变更: 添加了 *policy* 关键字。

   在 3.6 版本发生变更: *mangle_from_* 和 *maxheaderlen* 形参的默认行
   为是遵循策略。

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

      将将以 *msg* 为根的消息对象结构体的文本表示形式打印到创建
      "BytesGenerator" 实例时指定的输出文件。

      如果 "policy" 选项 "cte_type" 为 "8bit" (默认值)，则会将未被修改
      的原始已解析消息中的任何标头拷贝到输出，其中会重新生成与原始数据
      相同的高比特位组字节数据，并保留具有它们的任何消息体部分的非
      ASCII *Content-Transfer-Encoding*。 如果 "cte_type" 为 "7bit"，
      则会根据需要使用兼容 ASCII 的 *Content-Transfer-Encoding* 来转换
      高比特位组字节数据。 也就是说，将具有非 ASCII *Content-Transfer-
      Encoding* (*Content-Transfer-Encoding: 8bit*) 的部分转换为兼容
      ASCII 的 *Content-Transfer-Encoding*，并使用 MIME "unknown-8bit"
      字符集来编码标头中不符合 RFC 的非 ASCII 字节数据，以使其符合 RFC
      。

      如果 *unixfrom* 为 "True"，则会在根消息对象的第一个 **RFC 5322**
      标头之前打印 Unix mailbox 格式 (参见 "mailbox") 所使用的封包标头
      分隔符。 如果根对象没有封包标头，则会创建一个标准标头。 默认值为
      "False"。 请注意对于子部分来说，不会打印任何封包标头。

      如果 *linesep* 不为 "None"，则会将其用作扁平化消息的所有行之间的
      分隔符。 如果 *linesep* 为 "None" (默认值)，则使用在 *policy* 中
      指定的值。

   clone(fp)

      返回此 "BytesGenerator" 实例的独立克隆，具有完全相同的选项设置，
      而 *fp* 为新的 *outfp*。

   write(s)

      使用 "ASCII" 编解码器和 "surrogateescape" 错误处理程序编码 *s*，
      并将其传递给传入到 "BytesGenerator" 的构造器的 *outfp* 的
      *write* 方法 。

作为一个便捷工具，"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()" 方法的任何文本写入到 *file-like object* *outfp*。
   *outfp* 必须支持接受字符串数据的 "write" 方法。

   如果可选的 *mangle_from_* 为 "True"，则会将一个 ">" 字符放到消息体
   中恰好以字符串 ""From "" 打头，即开头文本为 "From" 加一个空格的任何
   行的前面。 *mangle_from_* 默认为 *policy* 的 "mangle_from_" 设置值
   (对于 "compat32" 策略为 "True" 而对于所有其他策略则为 "False")。
   *mangle_from_* 被设计为在当消息以 Unix mbox 格式存储时使用 (参见
   "mailbox" 和 WHY THE CONTENT-LENGTH FORMAT IS BAD)。

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

   如果指定了 *policy*，则使用该策略来控制消息的生成。 如果 *policy*
   为 "None" (默认值)，则使用与传递给 "flatten" 的 "Message" 或
   "EmailMessage" 对象相关联的策略来控制消息的生成。 请参阅
   "email.policy" 了解有关 *policy* 所控制内容的详情。

   在 3.3 版本发生变更: 添加了 *policy* 关键字。

   在 3.6 版本发生变更: *mangle_from_* 和 *maxheaderlen* 形参的默认行
   为是遵循策略。

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

      将以 *msg* 为根的消息对象结构体的文本表示形式打印到当
      "Generator" 实例被创建时所指定的输出文件。

      如果 "policy" 选项 "cte_type" 为 "8bit"，则视同选项被设为 "7bit"
      来生成消息。 （这是必需的，因为字符串无法表示非 ASCII 字节数据。
      ） 将使用兼容 ASCII 的 *Content-Transfer-Encoding* 按需转换任何
      具有高比特位组的字节数据。 也就是说，将具有非 ASCII *Content-
      Transfer-Encoding* (*Content-Transfer-Encoding: 8bit*) 的部分转
      换为兼容 ASCII 的 *Content-Transfer-Encoding*，并使用 MIME
      "unknown-8bit" 字符集来编码标头中不符合 RFC 的非 ASCII 字节数据
      ，以使其符合 RFC。

      如果 *unixfrom* 为 "True"，则会在根消息对象的第一个 **RFC 5322**
      标头之前打印 Unix mailbox 格式 (参见 "mailbox") 所使用的封包标头
      分隔符。 如果根对象没有封包标头，则会创建一个标准标头。 默认值为
      "False"。 请注意对于子部分来说，不会打印任何封包标头。

      如果 *linesep* 不为 "None"，则会将其用作扁平化消息的所有行之间的
      分隔符。 如果 *linesep* 为 "None" (默认值)，则使用在 *policy* 中
      指定的值。

      在 3.2 版本发生变更: 添加了对重编码 "8bit" 消息体的支持，以及
      *linesep* 参数。

   clone(fp)

      返回此 "Generator" 实例的独立克隆，具有完全相同的选项设置，而
      *fp* 为新的 *outfp*。

   write(s)

      将 *s* 写入到传给 "Generator" 的构造器的 *outfp* 的 *write* 方法
      。 这足够为 "Generator" 实际提供可用于 "print()" 函数的文件类
      API。

作为一个便捷工具，"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* 部分的内容转换编码格式

   如果 *fmt* 为 "None"，则使用下列默认 *fmt*:

      "[忽略消息的非文本 (%(type)s) 部分，文件名 %(filename)s]"

   可选的 *_mangle_from_* 和 *maxheaderlen* 与 "Generator" 基类的相同
   。

-[ 备注 ]-

[1] 此语句假定你使用了正确的 "unixfrom" 设置，并且没有针对自动调整的
    "email.policy" 设置调用（例如，"refold_source" 必须为 "none"，这 *
    不是* 默认值）。 这也不是 100% 为真的，因为如果消息不遵循 RFC 标准
    则有时实际原始文本的信息会在解析错误恢复时丢失。 它的目标是在可能
    的情况下修复这些后续的边缘情况。
