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

**Source code:** 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.

As with the "email.parser" module, you aren’t limited to the
functionality of the bundled generator; you could write one from
scratch yourself.  However the bundled generator knows how to generate
most email in a standards-compliant way, should handle MIME and non-
MIME email messages just fine, and is designed so that the bytes-
oriented parsing and generation operations are inverses, assuming the
same non-transforming "policy" is used for both.  That is, parsing the
serialized byte stream via the "BytesParser" class and then
regenerating the serialized byte stream using "BytesGenerator" should
produce output identical to the input [1].  (On the other hand, using
the generator on an "EmailMessage" constructed by program may result
in changes to the "EmailMessage" object as defaults are filled in.)

The "Generator" class can be used to flatten a message into a text (as
opposed to binary) serialized representation, but since Unicode cannot
represent binary data directly, the message is of necessity
transformed into something that contains only ASCII characters, using
the standard email RFC Content Transfer Encoding techniques for
encoding email messages for transport over channels that are not “8
bit clean”.

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

   Return a "BytesGenerator" object that will write any message
   provided to the "flatten()" method, or any surrogateescape encoded
   text provided to the "write()" method, to the *file-like object*
   *outfp*. *outfp* must support a "write" method that accepts binary
   data.

   If optional *mangle_from_* is "True", put a ">" character in front
   of any line in the body that starts with the exact string ""From
   "", that is "From" followed by a space at the beginning of a line.
   *mangle_from_* defaults to the value of the "mangle_from_" setting
   of the *policy* (which is "True" for the "compat32" policy and
   "False" for all others). *mangle_from_* is intended for use when
   messages are stored in unix mbox format (see "mailbox" and WHY THE
   CONTENT-LENGTH FORMAT IS BAD).

   If *maxheaderlen* is not "None", refold any header lines that are
   longer than *maxheaderlen*, or if "0", do not rewrap any headers.
   If *manheaderlen* is "None" (the default), wrap headers and other
   message lines according to the *policy* settings.

   If *policy* is specified, use that policy to control message
   generation.  If *policy* is "None" (the default), use the policy
   associated with the "Message" or "EmailMessage" object passed to
   "flatten" to control the message generation.  See "email.policy"
   for details on what *policy* controls.

   New in version 3.2.

   Changed in version 3.3: Added the *policy* keyword.

   Changed in version 3.6: The default behavior of the *mangle_from_*
   and *maxheaderlen* parameters is to follow the policy.

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

      Print the textual representation of the message object structure
      rooted at *msg* to the output file specified when the
      "BytesGenerator" instance was created.

      If the "policy" option "cte_type" is "8bit" (the default), copy
      any headers in the original parsed message that have not been
      modified to the output with any bytes with the high bit set
      reproduced as in the original, and preserve the non-ASCII
      *Content-Transfer-Encoding* of any body parts that have them. If
      "cte_type" is "7bit", convert the bytes with the high bit set as
      needed using an ASCII-compatible *Content-Transfer-Encoding*.
      That is, transform parts with non-ASCII *Content-Transfer-
      Encoding* (*Content-Transfer-Encoding: 8bit*) to an ASCII
      compatible *Content-Transfer-Encoding*, and encode RFC-invalid
      non-ASCII bytes in headers using the MIME "unknown-8bit"
      character set, thus rendering them RFC-compliant.

      If *unixfrom* is "True", print the envelope header delimiter
      used by the Unix mailbox format (see "mailbox") before the first
      of the **RFC 5322** headers of the root message object.  If the
      root object has no envelope header, craft a standard one.  The
      default is "False". Note that for subparts, no envelope header
      is ever printed.

      If *linesep* is not "None", use it as the separator character
      between all the lines of the flattened message.  If *linesep* is
      "None" (the default), use the value specified in the *policy*.

   clone(fp)

      Return an independent clone of this "BytesGenerator" instance
      with the exact same option settings, and *fp* as the new
      *outfp*.

   write(s)

      Encode *s* using the "ASCII" codec and the "surrogateescape"
      error handler, and pass it to the *write* method of the *outfp*
      passed to the "BytesGenerator"’s constructor.

As a convenience, "EmailMessage" provides the methods "as_bytes()" and
"bytes(aMessage)" (a.k.a. "__bytes__()"), which simplify the
generation of a serialized binary representation of a message object.
For more detail, see "email.message".

Because strings cannot represent binary data, the "Generator" class
must convert any binary data in any message it flattens to an ASCII
compatible format, by converting them to an ASCII compatible *Content-
Transfer_Encoding*.  Using the terminology of the email RFCs, you can
think of this as "Generator" serializing to an I/O stream that is not
“8 bit clean”.  In other words, most applications will want to be
using "BytesGenerator", and not "Generator".

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

   Return a "Generator" object that will write any message provided to
   the "flatten()" method, or any text provided to the "write()"
   method, to the *file-like object* *outfp*.  *outfp* must support a
   "write" method that accepts string data.

   If optional *mangle_from_* is "True", put a ">" character in front
   of any line in the body that starts with the exact string ""From
   "", that is "From" followed by a space at the beginning of a line.
   *mangle_from_* defaults to the value of the "mangle_from_" setting
   of the *policy* (which is "True" for the "compat32" policy and
   "False" for all others). *mangle_from_* is intended for use when
   messages are stored in unix mbox format (see "mailbox" and WHY THE
   CONTENT-LENGTH FORMAT IS BAD).

   If *maxheaderlen* is not "None", refold any header lines that are
   longer than *maxheaderlen*, or if "0", do not rewrap any headers.
   If *manheaderlen* is "None" (the default), wrap headers and other
   message lines according to the *policy* settings.

   If *policy* is specified, use that policy to control message
   generation.  If *policy* is "None" (the default), use the policy
   associated with the "Message" or "EmailMessage" object passed to
   "flatten" to control the message generation.  See "email.policy"
   for details on what *policy* controls.

   Changed in version 3.3: Added the *policy* keyword.

   Changed in version 3.6: The default behavior of the *mangle_from_*
   and *maxheaderlen* parameters is to follow the policy.

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

      Print the textual representation of the message object structure
      rooted at *msg* to the output file specified when the
      "Generator" instance was created.

      If the "policy" option "cte_type" is "8bit", generate the
      message as if the option were set to "7bit". (This is required
      because strings cannot represent non-ASCII bytes.) Convert any
      bytes with the high bit set as needed using an ASCII-compatible
      *Content-Transfer-Encoding*.  That is, transform parts with non-
      ASCII *Cotnent-Transfer-Encoding* (*Content-Transfer-Encoding:
      8bit*) to an ASCII compatible *Content-Transfer-Encoding*, and
      encode RFC-invalid non-ASCII bytes in headers using the MIME
      "unknown-8bit" character set, thus rendering them RFC-compliant.

      If *unixfrom* is "True", print the envelope header delimiter
      used by the Unix mailbox format (see "mailbox") before the first
      of the **RFC 5322** headers of the root message object.  If the
      root object has no envelope header, craft a standard one.  The
      default is "False". Note that for subparts, no envelope header
      is ever printed.

      If *linesep* is not "None", use it as the separator character
      between all the lines of the flattened message.  If *linesep* is
      "None" (the default), use the value specified in the *policy*.

      Changed in version 3.2: Added support for re-encoding "8bit"
      message bodies, and the *linesep* argument.

   clone(fp)

      Return an independent clone of this "Generator" instance with
      the exact same options, and *fp* as the new *outfp*.

   write(s)

      Write *s* to the *write* method of the *outfp* passed to the
      "Generator"’s constructor.  This provides just enough file-like
      API for "Generator" instances to be used in the "print()"
      function.

As a convenience, "EmailMessage" provides the methods "as_string()"
and "str(aMessage)" (a.k.a. "__str__()"), which simplify the
generation of a formatted string representation of a message object.
For more detail, see "email.message".

The "email.generator" module also provides a derived class,
"DecodedGenerator", which is like the "Generator" base class, except
that non-*text* parts are not serialized, but are instead represented
in the output stream by a string derived from a template filled in
with information about the part.

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

   Act like "Generator", except that for any subpart of the message
   passed to "Generator.flatten()", if the subpart is of main type
   *text*, print the decoded payload of the subpart, and if the main
   type is not *text*, instead of printing it fill in the string *fmt*
   using information from the part and print the resulting filled-in
   string.

   To fill in *fmt*, execute "fmt % part_info", where "part_info" is a
   dictionary composed of the following keys and values:

   * "type" – Full MIME type of the non-*text* part

   * "maintype" – Main MIME type of the non-*text* part

   * "subtype" – Sub-MIME type of the non-*text* part

   * "filename" – Filename of the non-*text* part

   * "description" – Description associated with the non-*text* part

   * "encoding" – Content transfer encoding of the non-*text* part

   If *fmt* is "None", use the following default *fmt*:

      “[Non-text (%(type)s) part of message omitted, filename
      %(filename)s]”

   Optional *_mangle_from_* and *maxheaderlen* are as with the
   "Generator" base class.

-[ Footnotes ]-

[1] This statement assumes that you use the appropriate setting for
    "unixfrom", and that there are no "policy" settings calling for
    automatic adjustments (for example, "refold_source" must be
    "none", which is *not* the default).  It is also not 100% true,
    since if the message does not conform to the RFC standards
    occasionally information about the exact original text is lost
    during parsing error recovery.  It is a goal to fix these latter
    edge cases when possible.
