summaryrefslogtreecommitdiffstats
path: root/Doc/library
diff options
context:
space:
mode:
authorR David Murray <rdmurray@bitdance.com>2013-10-17 02:48:40 (GMT)
committerR David Murray <rdmurray@bitdance.com>2013-10-17 02:48:40 (GMT)
commit3da240fd01e02a31e516847ba865a9f56d7cfcbc (patch)
tree056628df84b2e949fb793d75235e38766a16fbcc /Doc/library
parent1a1628819779110854d4e1ab490db2cab80e26b4 (diff)
downloadcpython-3da240fd01e02a31e516847ba865a9f56d7cfcbc.zip
cpython-3da240fd01e02a31e516847ba865a9f56d7cfcbc.tar.gz
cpython-3da240fd01e02a31e516847ba865a9f56d7cfcbc.tar.bz2
#18891: Complete new provisional email API.
This adds EmailMessage and, MIMEPart subclasses of Message with new API methods, and a ContentManager class used by the new methods. Also a new policy setting, content_manager. Patch was reviewed by Stephen J. Turnbull and Serhiy Storchaka, and reflects their feedback. I will ideally add some examples of using the new API to the documentation before the final release.
Diffstat (limited to 'Doc/library')
-rw-r--r--Doc/library/email.contentmanager.rst427
-rw-r--r--Doc/library/email.message.rst18
-rw-r--r--Doc/library/email.policy.rst34
-rw-r--r--Doc/library/email.rst1
4 files changed, 465 insertions, 15 deletions
diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst
new file mode 100644
index 0000000..f3ba794
--- /dev/null
+++ b/Doc/library/email.contentmanager.rst
@@ -0,0 +1,427 @@
+:mod:`email.contentmanager`: Managing MIME Content
+--------------------------------------------------
+
+.. module:: email.contentmanager
+ :synopsis: Storing and Retrieving Content from MIME Parts
+
+.. moduleauthor:: R. David Murray <rdmurray@bitdance.com>
+.. sectionauthor:: R. David Murray <rdmurray@bitdance.com>
+
+
+.. note::
+
+ The contentmanager module has been included in the standard library on a
+ :term:`provisional basis <provisional package>`. Backwards incompatible
+ changes (up to and including removal of the module) may occur if deemed
+ necessary by the core developers.
+
+.. versionadded:: 3.4
+ as a :term:`provisional module <provisional package>`.
+
+The :mod:`~email.message` module provides a class that can represent an
+arbitrary email message. That basic message model has a useful and flexible
+API, but it provides only a lower-level API for interacting with the generic
+parts of a message (the headers, generic header parameters, and the payload,
+which may be a list of sub-parts). This module provides classes and tools
+that provide an enhanced and extensible API for dealing with various specific
+types of content, including the ability to retrieve the content of the message
+as a specialized object type rather than as a simple bytes object. The module
+automatically takes care of the RFC-specified MIME details (required headers
+and parameters, etc.) for the certain common content types content properties,
+and support for additional types can be added by an application using the
+extension mechanisms.
+
+This module defines the eponymous "Content Manager" classes. The base
+:class:`.ContentManager` class defines an API for registering content
+management functions which extract data from ``Message`` objects or insert data
+and headers into ``Message`` objects, thus providing a way of converting
+between ``Message`` objects containing data and other representations of that
+data (Python data types, specialized Python objects, external files, etc). The
+module also defines one concrete content manager: :data:`raw_data_manager`
+converts between MIME content types and ``str`` or ``bytes`` data. It also
+provides a convenient API for managing the MIME parameters when inserting
+content into ``Message``\ s. It also handles inserting and extracting
+``Message`` objects when dealing with the ``message/rfc822`` content type.
+
+Another part of the enhanced interface is subclasses of
+:class:`~email.message.Message` that provide new convenience API functions,
+including convenience methods for calling the Content Managers derived from
+this module.
+
+.. note::
+
+ Although :class:`.EmailMessage` and :class:`.MIMEPart` are currently
+ documented in this module because of the provisional nature of the code, the
+ implementation lives in the :mod:`email.message` module.
+
+
+.. class:: EmailMessage(policy=default)
+
+ If *policy* is specified (it must be an instance of a :mod:`~email.policy`
+ class) use the rules it specifies to udpate and serialize the representation
+ of the message. If *policy* is not set, use the
+ :class:`~email.policy.default` policy, which follows the rules of the email
+ RFCs except for line endings (instead of the RFC mandated ``\r\n``, it uses
+ the Python standard ``\n`` line endings). For more information see the
+ :mod:`~email.policy` documentation.
+
+ This class is a subclass of :class:`~email.message.Message`. It adds
+ the following methods:
+
+
+ .. attribute:: is_attachment
+
+ Set to ``True`` if there is a :mailheader:`Content-Disposition` header
+ and its (case insensitive) value is ``attachment``, ``False`` otherwise.
+
+
+ .. method:: get_body(preferencelist=('related', 'html', 'plain'))
+
+ Return the MIME part that is the best candidate to be the "body" of the
+ message.
+
+ *preferencelist* must be a sequence of strings from the set ``related``,
+ ``html``, and ``plain``, and indicates the order of preference for the
+ content type of the part returned.
+
+ Start looking for candidate matches with the object on which the
+ ``get_body`` method is called.
+
+ If ``related`` is not included in *preferencelist*, consider the root
+ part (or subpart of the root part) of any related encountered as a
+ candidate if the (sub-)part matches a preference.
+
+ When encountering a ``multipart/related``, check the ``start`` parameter
+ and if a part with a matching :mailheader:`Content-ID` is found, consider
+ only it when looking for candidate matches. Otherwise consider only the
+ first (default root) part of the ``multipart/related``.
+
+ If a part has a :mailheader:``Content-Disposition`` header, only consider
+ the part a candidate match if the value of the header is ``inline``.
+
+ If none of the candidates matches any of the preferences in
+ *preferneclist*, return ``None``.
+
+ Notes: (1) For most applications the only *preferencelist* combinations
+ that really make sense are ``('plain',)``, ``('html', 'plain')``, and the
+ default, ``('related', 'html', 'plain')``. (2) Because matching starts
+ with the object on which ``get_body`` is called, calling ``get_body`` on
+ a ``multipart/related`` will return the object itself unless
+ *preferencelist* has a non-default value. (3) Messages (or message parts)
+ that do not specify a :mailheader:`Content-Type` or whose
+ :mailheader:`Content-Type` header is invalid will be treated as if they
+ are of type ``text/plain``, which may occasionally cause ``get_body`` to
+ return unexpected results.
+
+
+ .. method:: iter_attachments()
+
+ Return an iterator over all of the parts of the message that are not
+ candidate "body" parts. That is, skip the first occurrence of each of
+ ``text/plain``, ``text/html``, ``multipart/related``, or
+ ``multipart/alternative`` (unless they are explicitly marked as
+ attachments via :mailheader:`Content-Disposition: attachment`), and
+ return all remaining parts. When applied directly to a
+ ``multipart/related``, return an iterator over the all the related parts
+ except the root part (ie: the part pointed to by the ``start`` parameter,
+ or the first part if there is no ``start`` parameter or the ``start``
+ parameter doesn't match the :mailheader:`Content-ID` of any of the
+ parts). When applied directly to a ``multipart/alternative`` or a
+ non-``multipart``, return an empty iterator.
+
+
+ .. method:: iter_parts()
+
+ Return an iterator over all of the immediate sub-parts of the message,
+ which will be empty for a non-``multipart``. (See also
+ :meth:``~email.message.walk``.)
+
+
+ .. method:: get_content(*args, content_manager=None, **kw)
+
+ Call the ``get_content`` method of the *content_manager*, passing self
+ as the message object, and passing along any other arguments or keywords
+ as additional arguments. If *content_manager* is not specified, use
+ the ``content_manager`` specified by the current :mod:`~email.policy`.
+
+
+ .. method:: set_content(*args, content_manager=None, **kw)
+
+ Call the ``set_content`` method of the *content_manager*, passing self
+ as the message object, and passing along any other arguments or keywords
+ as additional arguments. If *content_manager* is not specified, use
+ the ``content_manager`` specified by the current :mod:`~email.policy`.
+
+
+ .. method:: make_related(boundary=None)
+
+ Convert a non-``multipart`` message into a ``multipart/related`` message,
+ moving any existing :mailheader:`Content-` headers and payload into a
+ (new) first part of the ``multipart``. If *boundary* is specified, use
+ it as the boundary string in the multipart, otherwise leave the boundary
+ to be automatically created when it is needed (for example, when the
+ message is serialized).
+
+
+ .. method:: make_alternative(boundary=None)
+
+ Convert a non-``multipart`` or a ``multipart/related`` into a
+ ``multipart/alternative``, moving any existing :mailheader:`Content-`
+ headers and payload into a (new) first part of the ``multipart``. If
+ *boundary* is specified, use it as the boundary string in the multipart,
+ otherwise leave the boundary to be automatically created when it is
+ needed (for example, when the message is serialized).
+
+
+ .. method:: make_mixed(boundary=None)
+
+ Convert a non-``multipart``, a ``multipart/related``, or a
+ ``multipart-alternative`` into a ``multipart/mixed``, moving any existing
+ :mailheader:`Content-` headers and payload into a (new) first part of the
+ ``multipart``. If *boundary* is specified, use it as the boundary string
+ in the multipart, otherwise leave the boundary to be automatically
+ created when it is needed (for example, when the message is serialized).
+
+
+ .. method:: add_related(*args, content_manager=None, **kw)
+
+ If the message is a ``multipart/related``, create a new message
+ object, pass all of the arguments to its :meth:`set_content` method,
+ and :meth:`~email.message.Message.attach` it to the ``multipart``. If
+ the message is a non-``multipart``, call :meth:`make_related` and then
+ proceed as above. If the message is any other type of ``multipart``,
+ raise a :exc:`TypeError`. If *content_manager* is not specified, use
+ the ``content_manager`` specified by the current :mod:`~email.policy`.
+ If the added part has no :mailheader:`Content-Disposition` header,
+ add one with the value ``inline``.
+
+
+ .. method:: add_alternative(*args, content_manager=None, **kw)
+
+ If the message is a ``multipart/alternative``, create a new message
+ object, pass all of the arguments to its :meth:`set_content` method, and
+ :meth:`~email.message.Message.attach` it to the ``multipart``. If the
+ message is a non-``multipart`` or ``multipart/related``, call
+ :meth:`make_alternative` and then proceed as above. If the message is
+ any other type of ``multipart``, raise a :exc:`TypeError`. If
+ *content_manager* is not specified, use the ``content_manager`` specified
+ by the current :mod:`~email.policy`.
+
+
+ .. method:: add_attachment(*args, content_manager=None, **kw)
+
+ If the message is a ``multipart/mixed``, create a new message object,
+ pass all of the arguments to its :meth:`set_content` method, and
+ :meth:`~email.message.Message.attach` it to the ``multipart``. If the
+ message is a non-``multipart``, ``multipart/related``, or
+ ``multipart/alternative``, call :meth:`make_mixed` and then proceed as
+ above. If *content_manager* is not specified, use the ``content_manager``
+ specified by the current :mod:`~email.policy`. If the added part
+ has no :mailheader:`Content-Disposition` header, add one with the value
+ ``attachment``. This method can be used both for explicit attachments
+ (:mailheader:`Content-Disposition: attachment` and ``inline`` attachments
+ (:mailheader:`Content-Disposition: inline`), by passing appropriate
+ options to the ``content_manager``.
+
+
+ .. method:: clear()
+
+ Remove the payload and all of the headers.
+
+
+ .. method:: clear_content()
+
+ Remove the payload and all of the :exc:`Content-` headers, leaving
+ all other headers intact and in their original order.
+
+
+.. class:: ContentManager()
+
+ Base class for content managers. Provides the standard registry mechanisms
+ to register converters between MIME content and other representations, as
+ well as the ``get_content`` and ``set_content`` dispatch methods.
+
+
+ .. method:: get_content(msg, *args, **kw)
+
+ Look up a handler function based on the ``mimetype`` of *msg* (see next
+ paragraph), call it, passing through all arguments, and return the result
+ of the call. The expectation is that the handler will extract the
+ payload from *msg* and return an object that encodes information about
+ the extracted data.
+
+ To find the handler, look for the following keys in the registry,
+ stopping with the first one found:
+
+ * the string representing the full MIME type (``maintype/subtype``)
+ * the string representing the ``maintype``
+ * the empty string
+
+ If none of these keys produce a handler, raise a :exc:`KeyError` for the
+ full MIME type.
+
+
+ .. method:: set_content(msg, obj, *args, **kw)
+
+ If the ``maintype`` is ``multipart``, raise a :exc:`TypeError`; otherwise
+ look up a handler function based on the type of *obj* (see next
+ paragraph), call :meth:`~email.message.EmailMessage.clear_content` on the
+ *msg*, and call the handler function, passing through all arguments. The
+ expectation is that the handler will transform and store *obj* into
+ *msg*, possibly making other changes to *msg* as well, such as adding
+ various MIME headers to encode information needed to interpret the stored
+ data.
+
+ To find the handler, obtain the type of *obj* (``typ = type(obj)``), and
+ look for the following keys in the registry, stopping with the first one
+ found:
+
+ * the type itself (``typ``)
+ * the type's fully qualified name (``typ.__module__ + '.' +
+ typ.__qualname__``).
+ * the type's qualname (``typ.__qualname__``)
+ * the type's name (``typ.__name__``).
+
+ If none of the above match, repeat all of the checks above for each of
+ the types in the :term:`MRO` (``typ.__mro__``). Finally, if no other key
+ yields a handler, check for a handler for the key ``None``. If there is
+ no handler for ``None``, raise a :exc:`KeyError` for the fully
+ qualified name of the type.
+
+ Also add a :mailheader:`MIME-Version` header if one is not present (see
+ also :class:`.MIMEPart`).
+
+
+ .. method:: add_get_handler(key, handler)
+
+ Record the function *handler* as the handler for *key*. For the possible
+ values of *key*, see :meth:`get_content`.
+
+
+ .. method:: add_set_handler(typekey, handler)
+
+ Record *handler* as the function to call when an object of a type
+ matching *typekey* is passed to :meth:`set_content`. For the possible
+ values of *typekey*, see :meth:`set_content`.
+
+
+.. class:: MIMEPart(policy=default)
+
+ This class represents a subpart of a MIME message. It is identical to
+ :class:`EmailMessage`, except that no :mailheader:`MIME-Version` headers are
+ added when :meth:`~EmailMessage.set_content` is called, since sub-parts do
+ not need their own :mailheader:`MIME-Version` headers.
+
+
+Content Manager Instances
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Currently the email package provides only one concrete content manager,
+:data:`raw_data_manager`, although more may be added in the future.
+:data:`raw_data_manager` is the
+:attr:`~email.policy.EmailPolicy.content_manager` provided by
+:attr:`~email.policy.EmailPolicy` and its derivatives.
+
+
+.. data:: raw_data_manager
+
+ This content manager provides only a minimum interface beyond that provided
+ by :class:`~email.message.Message` itself: it deals only with text, raw
+ byte strings, and :class:`~email.message.Message` objects. Nevertheless, it
+ provides significant advantages compared to the base API: ``get_content`` on
+ a text part will return a unicode string without the application needing to
+ manually decode it, ``set_content`` provides a rich set of options for
+ controlling the headers added to a part and controlling the content transfer
+ encoding, and it enables the use of the various ``add_`` methods, thereby
+ simplifying the creation of multipart messages.
+
+ .. method:: get_content(msg, errors='replace')
+
+ Return the payload of the part as either a string (for ``text`` parts), a
+ :class:`~email.message.EmailMessage` object (for ``message/rfc822``
+ parts), or a ``bytes`` object (for all other non-multipart types). Raise
+ a :exc:`KeyError` if called on a ``multipart``. If the part is a
+ ``text`` part and *errors* is specified, use it as the error handler when
+ decoding the payload to unicode. The default error handler is
+ ``replace``.
+
+ .. method:: set_content(msg, <'str'>, subtype="plain", charset='utf-8' \
+ cte=None, \
+ disposition=None, filename=None, cid=None, \
+ params=None, headers=None)
+ set_content(msg, <'bytes'>, maintype, subtype, cte="base64", \
+ disposition=None, filename=None, cid=None, \
+ params=None, headers=None)
+ set_content(msg, <'Message'>, cte=None, \
+ disposition=None, filename=None, cid=None, \
+ params=None, headers=None)
+ set_content(msg, <'list'>, subtype='mixed', \
+ disposition=None, filename=None, cid=None, \
+ params=None, headers=None)
+
+ Add headers and payload to *msg*:
+
+ Add a :mailheader:`Content-Type` header with a ``maintype/subtype``
+ value.
+
+ * For ``str``, set the MIME ``maintype`` to ``text``, and set the
+ subtype to *subtype* if it is specified, or ``plain`` if it is not.
+ * For ``bytes``, use the specified *maintype* and *subtype*, or
+ raise a :exc:`TypeError` if they are not specified.
+ * For :class:`~email.message.Message` objects, set the maintype to
+ ``message``, and set the subtype to *subtype* if it is specified
+ or ``rfc822`` if it is not. If *subtype* is ``partial``, raise an
+ error (``bytes`` objects must be used to construct
+ ``message/partial`` parts).
+ * For *<'list'>*, which should be a list of
+ :class:`~email.message.Message` objects, set the ``maintype`` to
+ ``multipart``, and the ``subtype`` to *subtype* if it is
+ specified, and ``mixed`` if it is not. If the message parts in
+ the *<'list'>* have :mailheader:`MIME-Version` headers, remove
+ them.
+
+ If *charset* is provided (which is valid only for ``str``), encode the
+ string to bytes using the specified character set. The default is
+ ``utf-8``. If the specified *charset* is a known alias for a standard
+ MIME charset name, use the standard charset instead.
+
+ If *cte* is set, encode the payload using the specified content transfer
+ encoding, and set the :mailheader:`Content-Transfer-Endcoding` header to
+ that value. For ``str`` objects, if it is not set use heuristics to
+ determine the most compact encoding. Possible values for *cte* are
+ ``quoted-printable``, ``base64``, ``7bit``, ``8bit``, and ``binary``.
+ If the input cannot be encoded in the specified encoding (eg: ``7bit``),
+ raise a :exc:`ValueError`. For :class:`~email.message.Message`, per
+ :rfc:`2046`, raise an error if a *cte* of ``quoted-printable`` or
+ ``base64`` is requested for *subtype* ``rfc822``, and for any *cte*
+ other than ``7bit`` for *subtype* ``external-body``. For
+ ``message/rfc822``, use ``8bit`` if *cte* is not specified. For all
+ other values of *subtype*, use ``7bit``.
+
+ .. note:: A *cte* of ``binary`` does not actually work correctly yet.
+ The ``Message`` object as modified by ``set_content`` is correct, but
+ :class:`~email.generator.BytesGenerator` does not serialize it
+ correctly.
+
+ If *disposition* is set, use it as the value of the
+ :mailheader:`Content-Disposition` header. If not specified, and
+ *filename* is specified, add the header with the value ``attachment``.
+ If it is not specified and *filename* is also not specified, do not add
+ the header. The only valid values for *disposition* are ``attachment``
+ and ``inline``.
+
+ If *filename* is specified, use it as the value of the ``filename``
+ parameter of the :mailheader:`Content-Disposition` header. There is no
+ default.
+
+ If *cid* is specified, add a :mailheader:`Content-ID` header with
+ *cid* as its value.
+
+ If *params* is specified, iterate its ``items`` method and use the
+ resulting ``(key, value)`` pairs to set additional paramters on the
+ :mailheader:`Content-Type` header.
+
+ If *headers* is specified and is a list of strings of the form
+ ``headername: headervalue`` or a list of ``header`` objects
+ (distinguised from strings by having a ``name`` attribute), add the
+ headers to *msg*.
diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index 4a34c36..f278a0a 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -33,10 +33,11 @@ Here are the methods of the :class:`Message` class:
.. class:: Message(policy=compat32)
- The *policy* argument determiens the :mod:`~email.policy` that will be used
- to update the message model. The default value, :class:`compat32
- <email.policy.Compat32>` maintains backward compatibility with the
- Python 3.2 version of the email package. For more information see the
+ If *policy* is specified (it must be an instance of a :mod:`~email.policy`
+ class) use the rules it specifies to udpate and serialize the representation
+ of the message. If *policy* is not set, use the :class`compat32
+ <email.policy.Compat32>` policy, which maintains backward compatibility with
+ the Python 3.2 version of the email package. For more information see the
:mod:`~email.policy` documentation.
.. versionchanged:: 3.3 The *policy* keyword argument was added.
@@ -465,7 +466,8 @@ Here are the methods of the :class:`Message` class:
to ``False``.
- .. method:: set_param(param, value, header='Content-Type', requote=True, charset=None, language='')
+ .. method:: set_param(param, value, header='Content-Type', requote=True,
+ charset=None, language='', replace=False)
Set a parameter in the :mailheader:`Content-Type` header. If the
parameter already exists in the header, its value will be replaced with
@@ -482,6 +484,12 @@ Here are the methods of the :class:`Message` class:
language, defaulting to the empty string. Both *charset* and *language*
should be strings.
+ If *replace* is ``False`` (the default) the header is moved to the
+ end of the list of headers. If *replace* is ``True``, the header
+ will be updated in place.
+
+ .. versionchanged: 3.4 ``replace`` keyword was added.
+
.. method:: del_param(param, header='content-type', requote=True)
diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst
index 5856879..c2f9e6a 100644
--- a/Doc/library/email.policy.rst
+++ b/Doc/library/email.policy.rst
@@ -371,7 +371,7 @@ added matters. To illustrate::
to) :rfc:`5322`, :rfc:`2047`, and the current MIME RFCs.
This policy adds new header parsing and folding algorithms. Instead of
- simple strings, headers are custom objects with custom attributes depending
+ simple strings, headers are ``str`` subclasses with attributes that depend
on the type of the field. The parsing and folding algorithm fully implement
:rfc:`2047` and :rfc:`5322`.
@@ -408,6 +408,20 @@ added matters. To illustrate::
fields are treated as unstructured. This list will be completed before
the extension is marked stable.)
+ .. attribute:: content_manager
+
+ An object with at least two methods: get_content and set_content. When
+ the :meth:`~email.message.Message.get_content` or
+ :meth:`~email.message.Message.set_content` method of a
+ :class:`~email.message.Message` object is called, it calls the
+ corresponding method of this object, passing it the message object as its
+ first argument, and any arguments or keywords that were passed to it as
+ additional arguments. By default ``content_manager`` is set to
+ :data:`~email.contentmanager.raw_data_manager`.
+
+ .. versionadded 3.4
+
+
The class provides the following concrete implementations of the abstract
methods of :class:`Policy`:
@@ -427,7 +441,7 @@ added matters. To illustrate::
The name is returned unchanged. If the input value has a ``name``
attribute and it matches *name* ignoring case, the value is returned
unchanged. Otherwise the *name* and *value* are passed to
- ``header_factory``, and the resulting custom header object is returned as
+ ``header_factory``, and the resulting header object is returned as
the value. In this case a ``ValueError`` is raised if the input value
contains CR or LF characters.
@@ -435,7 +449,7 @@ added matters. To illustrate::
If the value has a ``name`` attribute, it is returned to unmodified.
Otherwise the *name*, and the *value* with any CR or LF characters
- removed, are passed to the ``header_factory``, and the resulting custom
+ removed, are passed to the ``header_factory``, and the resulting
header object is returned. Any surrogateescaped bytes get turned into
the unicode unknown-character glyph.
@@ -445,9 +459,9 @@ added matters. To illustrate::
A value is considered to be a 'source value' if and only if it does not
have a ``name`` attribute (having a ``name`` attribute means it is a
header object of some sort). If a source value needs to be refolded
- according to the policy, it is converted into a custom header object by
+ according to the policy, it is converted into a header object by
passing the *name* and the *value* with any CR and LF characters removed
- to the ``header_factory``. Folding of a custom header object is done by
+ to the ``header_factory``. Folding of a header object is done by
calling its ``fold`` method with the current policy.
Source values are split into lines using :meth:`~str.splitlines`. If
@@ -502,23 +516,23 @@ With all of these :class:`EmailPolicies <.EmailPolicy>`, the effective API of
the email package is changed from the Python 3.2 API in the following ways:
* Setting a header on a :class:`~email.message.Message` results in that
- header being parsed and a custom header object created.
+ header being parsed and a header object created.
* Fetching a header value from a :class:`~email.message.Message` results
- in that header being parsed and a custom header object created and
+ in that header being parsed and a header object created and
returned.
- * Any custom header object, or any header that is refolded due to the
+ * Any header object, or any header that is refolded due to the
policy settings, is folded using an algorithm that fully implements the
RFC folding algorithms, including knowing where encoded words are required
and allowed.
From the application view, this means that any header obtained through the
-:class:`~email.message.Message` is a custom header object with custom
+:class:`~email.message.Message` is a header object with extra
attributes, whose string value is the fully decoded unicode value of the
header. Likewise, a header may be assigned a new value, or a new header
created, using a unicode string, and the policy will take care of converting
the unicode string into the correct RFC encoded form.
-The custom header objects and their attributes are described in
+The header objects and their attributes are described in
:mod:`~email.headerregistry`.
diff --git a/Doc/library/email.rst b/Doc/library/email.rst
index a6cbbce..331d2ef 100644
--- a/Doc/library/email.rst
+++ b/Doc/library/email.rst
@@ -53,6 +53,7 @@ Contents of the :mod:`email` package documentation:
email.generator.rst
email.policy.rst
email.headerregistry.rst
+ email.contentmanager.rst
email.mime.rst
email.header.rst
email.charset.rst