summaryrefslogtreecommitdiff
path: root/Doc/library/email.message.rst
diff options
context:
space:
mode:
Diffstat (limited to 'Doc/library/email.message.rst')
-rw-r--r--Doc/library/email.message.rst719
1 files changed, 387 insertions, 332 deletions
diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index 2907975357..32852e7069 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -3,91 +3,102 @@
.. module:: email.message
:synopsis: The base class representing email messages.
+.. moduleauthor:: R. David Murray <rdmurray@bitdance.com>
+.. sectionauthor:: R. David Murray <rdmurray@bitdance.com>,
+ Barry A. Warsaw <barry@python.org>
**Source code:** :source:`Lib/email/message.py`
--------------
-The central class in the :mod:`email` package is the :class:`Message` class,
-imported from the :mod:`email.message` module. It is the base class for the
-:mod:`email` object model. :class:`Message` provides the core functionality for
-setting and querying header fields, and for accessing message bodies.
-
-Conceptually, a :class:`Message` object consists of *headers* and *payloads*.
-Headers are :rfc:`2822` style field names and values where the field name and
-value are separated by a colon. The colon is not part of either the field name
-or the field value.
-
-Headers are stored and returned in case-preserving form but are matched
-case-insensitively. There may also be a single envelope header, also known as
-the *Unix-From* header or the ``From_`` header. The payload is either a string
-in the case of simple message objects or a list of :class:`Message` objects for
-MIME container documents (e.g. :mimetype:`multipart/\*` and
-:mimetype:`message/rfc822`).
-
-:class:`Message` objects provide a mapping style interface for accessing the
-message headers, and an explicit interface for accessing both the headers and
-the payload. It provides convenience methods for generating a flat text
-representation of the message object tree, for accessing commonly used header
-parameters, and for recursively walking over the object tree.
-
-Here are the methods of the :class:`Message` class:
-
-
-.. class:: Message(policy=compat32)
-
- If *policy* is specified (it must be an instance of a :mod:`~email.policy`
- class) use the rules it specifies to update 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
+.. versionadded:: 3.6 [1]_
+
+The central class in the :mod:`email` package is the :class:`EmailMessage`
+class, imported from the :mod:`email.message` module. It is the base class for
+the :mod:`email` object model. :class:`EmailMessage` provides the core
+functionality for setting and querying header fields, for accessing message
+bodies, and for creating or modifying structured messages.
+
+An email message consists of *headers* and a *payload* (which is also referred
+to as the *content*). Headers are :rfc:`5322` or :rfc:`6532` style field names
+and values, where the field name and value are separated by a colon. The colon
+is not part of either the field name or the field value. The payload may be a
+simple text message, or a binary object, or a structured sequence of
+sub-messages each with their own set of headers and their own payload. The
+latter type of payload is indicated by the message having a MIME type such as
+:mimetype:`multipart/\*` or :mimetype:`message/rfc822`.
+
+The conceptual model provided by an :class:`EmailMessage` object is that of an
+ordered dictionary of headers coupled with a *payload* that represents the
+:rfc:`5322` body of the message, which might be a list of sub-``EmailMessage``
+objects. In addition to the normal dictionary methods for accessing the header
+names and values, there are methods for accessing specialized information from
+the headers (for example the MIME content type), for operating on the payload,
+for generating a serialized version of the message, and for recursively walking
+over the object tree.
+
+The :class:`EmailMessage` dictionary-like interface is indexed by the header
+names, which must be ASCII values. The values of the dictionary are strings
+with some extra methods. Headers are stored and returned in case-preserving
+form, but field names are matched case-insensitively. Unlike a real dict,
+there is an ordering to the keys, and there can be duplicate keys. Additional
+methods are provided for working with headers that have duplicate keys.
+
+The *payload* is either a string or bytes object, in the case of simple message
+objects, or a list of :class:`EmailMessage` objects, for MIME container
+documents such as :mimetype:`multipart/\*` and :mimetype:`message/rfc822`
+message objects.
+
+
+.. class:: EmailMessage(policy=default)
+
+ If *policy* is specified 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.
- .. versionchanged:: 3.3 The *policy* keyword argument was added.
-
-
- .. method:: as_string(unixfrom=False, maxheaderlen=0, policy=None)
-
- Return the entire message flattened as a string. When optional *unixfrom*
- is true, the envelope header is included in the returned string.
- *unixfrom* defaults to ``False``. For backward compabitility reasons,
- *maxheaderlen* defaults to ``0``, so if you want a different value you
- must override it explicitly (the value specified for *max_line_length* in
- the policy will be ignored by this method). The *policy* argument may be
- used to override the default policy obtained from the message instance.
- This can be used to control some of the formatting produced by the
- method, since the specified *policy* will be passed to the ``Generator``.
-
- Flattening the message may trigger changes to the :class:`Message` if
- defaults need to be filled in to complete the transformation to a string
- (for example, MIME boundaries may be generated or modified).
-
- Note that this method is provided as a convenience and may not always
- format the message the way you want. For example, by default it does
- not do the mangling of lines that begin with ``From`` that is
- required by the unix mbox format. For more flexibility, instantiate a
- :class:`~email.generator.Generator` instance and use its
- :meth:`~email.generator.Generator.flatten` method directly. For example::
-
- from io import StringIO
- from email.generator import Generator
- fp = StringIO()
- g = Generator(fp, mangle_from_=True, maxheaderlen=60)
- g.flatten(msg)
- text = fp.getvalue()
+ .. method:: as_string(unixfrom=False, maxheaderlen=None, policy=None)
- If the message object contains binary data that is not encoded according
- to RFC standards, the non-compliant data will be replaced by unicode
- "unknown character" code points. (See also :meth:`.as_bytes` and
- :class:`~email.generator.BytesGenerator`.)
-
- .. versionchanged:: 3.4 the *policy* keyword argument was added.
+ Return the entire message flattened as a string. When optional
+ *unixfrom* is true, the envelope header is included in the returned
+ string. *unixfrom* defaults to ``False``. For backward compabitility
+ with the base :class:`~email.message.Message` class *maxheaderlen* is
+ accepted, but defaults to ``None``, which means that by default the line
+ length is controlled by the
+ :attr:`~email.policy.EmailPolicy.max_line_length` of the policy. The
+ *policy* argument may be used to override the default policy obtained
+ from the message instance. This can be used to control some of the
+ formatting produced by the method, since the specified *policy* will be
+ passed to the :class:`~email.generator.Generator`.
+
+ Flattening the message may trigger changes to the :class:`EmailMessage`
+ if defaults need to be filled in to complete the transformation to a
+ string (for example, MIME boundaries may be generated or modified).
+
+ Note that this method is provided as a convenience and may not be the
+ most useful way to serialize messages in your application, especially if
+ you are dealing with multiple messages. See
+ :class:`email.generator.Generator` for a more flexible API for
+ serializing messages. Note also that this method is restricted to
+ producing messages serialized as "7 bit clean" when
+ :attr:`~email.policy.EmailPolicy.utf8` is ``False``, which is the default.
+
+ .. versionchanged:: 3.6 the default behavior when *maxheaderlen*
+ is not specified was changed from defaulting to 0 to defaulting
+ to the value of *max_line_length* from the policy.
.. method:: __str__()
- Equivalent to :meth:`.as_string()`. Allows ``str(msg)`` to produce a
- string containing the formatted message.
+ Equivalent to `as_string(policy=self.policy.clone(utf8=True)`. Allows
+ ``str(msg)`` to produce a string containing the serialized message in a
+ readable format.
+
+ .. versionchanged:: 3.4 the method was changed to use ``utf8=True``,
+ thus producing an :rfc:`6531`-like message representation, instead of
+ being a direct alias for :meth:`as_string`.
.. method:: as_bytes(unixfrom=False, policy=None)
@@ -98,52 +109,42 @@ Here are the methods of the :class:`Message` class:
used to override the default policy obtained from the message instance.
This can be used to control some of the formatting produced by the
method, since the specified *policy* will be passed to the
- ``BytesGenerator``.
-
- Flattening the message may trigger changes to the :class:`Message` if
- defaults need to be filled in to complete the transformation to a string
- (for example, MIME boundaries may be generated or modified).
+ :class:`~email.generator.BytesGenerator`.
- Note that this method is provided as a convenience and may not always
- format the message the way you want. For example, by default it does
- not do the mangling of lines that begin with ``From`` that is
- required by the unix mbox format. For more flexibility, instantiate a
- :class:`~email.generator.BytesGenerator` instance and use its
- :meth:`~email.generator.BytesGenerator.flatten` method directly.
- For example::
+ Flattening the message may trigger changes to the :class:`EmailMessage`
+ if defaults need to be filled in to complete the transformation to a
+ string (for example, MIME boundaries may be generated or modified).
- from io import BytesIO
- from email.generator import BytesGenerator
- fp = BytesIO()
- g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60)
- g.flatten(msg)
- text = fp.getvalue()
-
- .. versionadded:: 3.4
+ Note that this method is provided as a convenience and may not be the
+ most useful way to serialize messages in your application, especially if
+ you are dealing with multiple messages. See
+ :class:`email.generator.BytesGenerator` for a more flexible API for
+ serializing messages.
.. method:: __bytes__()
Equivalent to :meth:`.as_bytes()`. Allows ``bytes(msg)`` to produce a
- bytes object containing the formatted message.
-
- .. versionadded:: 3.4
+ bytes object containing the serialized message.
.. method:: is_multipart()
Return ``True`` if the message's payload is a list of sub-\
- :class:`Message` objects, otherwise return ``False``. When
+ :class:`EmailMessage` objects, otherwise return ``False``. When
:meth:`is_multipart` returns ``False``, the payload should be a string
- object. (Note that :meth:`is_multipart` returning ``True`` does not
- necessarily mean that "msg.get_content_maintype() == 'multipart'" will
- return the ``True``. For example, ``is_multipart`` will return ``True``
- when the :class:`Message` is of type ``message/rfc822``.)
+ object (which might be a CTE encoded binary payload). Note that
+ :meth:`is_multipart` returning ``True`` does not necessarily mean that
+ "msg.get_content_maintype() == 'multipart'" will return the ``True``.
+ For example, ``is_multipart`` will return ``True`` when the
+ :class:`EmailMessage` is of type ``message/rfc822``.
.. method:: set_unixfrom(unixfrom)
- Set the message's envelope header to *unixfrom*, which should be a string.
+ Set the message's envelope header to *unixfrom*, which should be a
+ string. (See :class:`~mailbox.mboxMessage` for a brief description of
+ this header.)
.. method:: get_unixfrom()
@@ -152,109 +153,23 @@ Here are the methods of the :class:`Message` class:
envelope header was never set.
- .. method:: attach(payload)
-
- Add the given *payload* to the current payload, which must be ``None`` or
- a list of :class:`Message` objects before the call. After the call, the
- payload will always be a list of :class:`Message` objects. If you want to
- set the payload to a scalar object (e.g. a string), use
- :meth:`set_payload` instead.
-
-
- .. method:: get_payload(i=None, decode=False)
-
- Return the current payload, which will be a list of
- :class:`Message` objects when :meth:`is_multipart` is ``True``, or a
- string when :meth:`is_multipart` is ``False``. If the payload is a list
- and you mutate the list object, you modify the message's payload in place.
-
- With optional argument *i*, :meth:`get_payload` will return the *i*-th
- element of the payload, counting from zero, if :meth:`is_multipart` is
- ``True``. An :exc:`IndexError` will be raised if *i* is less than 0 or
- greater than or equal to the number of items in the payload. If the
- payload is a string (i.e. :meth:`is_multipart` is ``False``) and *i* is
- given, a :exc:`TypeError` is raised.
-
- Optional *decode* is a flag indicating whether the payload should be
- decoded or not, according to the :mailheader:`Content-Transfer-Encoding`
- header. When ``True`` and the message is not a multipart, the payload will
- be decoded if this header's value is ``quoted-printable`` or ``base64``.
- If some other encoding is used, or :mailheader:`Content-Transfer-Encoding`
- header is missing, the payload is
- returned as-is (undecoded). In all cases the returned value is binary
- data. If the message is a multipart and the *decode* flag is ``True``,
- then ``None`` is returned. If the payload is base64 and it was not
- perfectly formed (missing padding, characters outside the base64
- alphabet), then an appropriate defect will be added to the message's
- defect property (:class:`~email.errors.InvalidBase64PaddingDefect` or
- :class:`~email.errors.InvalidBase64CharactersDefect`, respectively).
-
- When *decode* is ``False`` (the default) the body is returned as a string
- without decoding the :mailheader:`Content-Transfer-Encoding`. However,
- for a :mailheader:`Content-Transfer-Encoding` of 8bit, an attempt is made
- to decode the original bytes using the ``charset`` specified by the
- :mailheader:`Content-Type` header, using the ``replace`` error handler.
- If no ``charset`` is specified, or if the ``charset`` given is not
- recognized by the email package, the body is decoded using the default
- ASCII charset.
-
-
- .. method:: set_payload(payload, charset=None)
-
- Set the entire message object's payload to *payload*. It is the client's
- responsibility to ensure the payload invariants. Optional *charset* sets
- the message's default character set; see :meth:`set_charset` for details.
-
- .. method:: set_charset(charset)
-
- Set the character set of the payload to *charset*, which can either be a
- :class:`~email.charset.Charset` instance (see :mod:`email.charset`), a
- string naming a character set, or ``None``. If it is a string, it will
- be converted to a :class:`~email.charset.Charset` instance. If *charset*
- is ``None``, the ``charset`` parameter will be removed from the
- :mailheader:`Content-Type` header (the message will not be otherwise
- modified). Anything else will generate a :exc:`TypeError`.
-
- If there is no existing :mailheader:`MIME-Version` header one will be
- added. If there is no existing :mailheader:`Content-Type` header, one
- will be added with a value of :mimetype:`text/plain`. Whether the
- :mailheader:`Content-Type` header already exists or not, its ``charset``
- parameter will be set to *charset.output_charset*. If
- *charset.input_charset* and *charset.output_charset* differ, the payload
- will be re-encoded to the *output_charset*. If there is no existing
- :mailheader:`Content-Transfer-Encoding` header, then the payload will be
- transfer-encoded, if needed, using the specified
- :class:`~email.charset.Charset`, and a header with the appropriate value
- will be added. If a :mailheader:`Content-Transfer-Encoding` header
- already exists, the payload is assumed to already be correctly encoded
- using that :mailheader:`Content-Transfer-Encoding` and is not modified.
-
- .. method:: get_charset()
-
- Return the :class:`~email.charset.Charset` instance associated with the
- message's payload.
-
- The following methods implement a mapping-like interface for accessing the
- message's :rfc:`2822` headers. Note that there are some semantic differences
+ The following methods implement the mapping-like interface for accessing the
+ message's headers. Note that there are some semantic differences
between these methods and a normal mapping (i.e. dictionary) interface. For
example, in a dictionary there are no duplicate keys, but here there may be
duplicate message headers. Also, in dictionaries there is no guaranteed
- order to the keys returned by :meth:`keys`, but in a :class:`Message` object,
- headers are always returned in the order they appeared in the original
- message, or were added to the message later. Any header deleted and then
- re-added are always appended to the end of the header list.
+ order to the keys returned by :meth:`keys`, but in an :class:`EmailMessage`
+ object, headers are always returned in the order they appeared in the
+ original message, or in which they were added to the message later. Any
+ header deleted and then re-added is always appended to the end of the
+ header list.
- These semantic differences are intentional and are biased toward maximal
- convenience.
+ These semantic differences are intentional and are biased toward
+ convenience in the most common use cases.
Note that in all cases, any envelope header present in the message is not
included in the mapping interface.
- In a model generated from bytes, any header values that (in contravention of
- the RFCs) contain non-ASCII bytes will, when retrieved through this
- interface, be represented as :class:`~email.header.Header` objects with
- a charset of `unknown-8bit`.
-
.. method:: __len__()
@@ -264,8 +179,8 @@ Here are the methods of the :class:`Message` class:
.. method:: __contains__(name)
Return true if the message object has a field named *name*. Matching is
- done case-insensitively and *name* should not include the trailing colon.
- Used for the ``in`` operator, e.g.::
+ done without regard to case and *name* does not include the trailing
+ colon. Used for the ``in`` operator. For example::
if 'message-id' in myMessage:
print('Message-ID:', myMessage['message-id'])
@@ -273,20 +188,23 @@ Here are the methods of the :class:`Message` class:
.. method:: __getitem__(name)
- Return the value of the named header field. *name* should not include the
+ Return the value of the named header field. *name* does not include the
colon field separator. If the header is missing, ``None`` is returned; a
:exc:`KeyError` is never raised.
Note that if the named field appears more than once in the message's
headers, exactly which of those field values will be returned is
undefined. Use the :meth:`get_all` method to get the values of all the
- extant named headers.
+ extant headers named *name*.
+
+ Using the standard (non-``compat32``) policies, the returned value is an
+ instance of a subclass of :class:`email.headerregistry.BaseHeader`.
.. method:: __setitem__(name, val)
Add a header to the message with field name *name* and value *val*. The
- field is appended to the end of the message's existing fields.
+ field is appended to the end of the message's existing headers.
Note that this does *not* overwrite or delete any existing header with the same
name. If you want to ensure that the new header is the only one present in the
@@ -295,6 +213,13 @@ Here are the methods of the :class:`Message` class:
del msg['subject']
msg['subject'] = 'Python roolz!'
+ If the :mod:`policy` defines certain haders to be unique (as the standard
+ policies do), this method may raise a :exc:`ValueError` when an attempt
+ is made to assign a value to such a header when one already exists. This
+ behavior is intentional for consistency's sake, but do not depend on it
+ as we may choose to make such assignments do an automatic deletion of the
+ existing header in the future.
+
.. method:: __delitem__(name)
@@ -323,9 +248,10 @@ Here are the methods of the :class:`Message` class:
Return the value of the named header field. This is identical to
:meth:`__getitem__` except that optional *failobj* is returned if the
- named header is missing (defaults to ``None``).
+ named header is missing (*failobj* defaults to ``None``).
- Here are some additional useful methods:
+
+ Here are some additional useful header related methods:
.. method:: get_all(name, failobj=None)
@@ -346,17 +272,19 @@ Here are the methods of the :class:`Message` class:
taken as the parameter name, with underscores converted to dashes (since
dashes are illegal in Python identifiers). Normally, the parameter will
be added as ``key="value"`` unless the value is ``None``, in which case
- only the key will be added. If the value contains non-ASCII characters,
- it can be specified as a three tuple in the format
- ``(CHARSET, LANGUAGE, VALUE)``, where ``CHARSET`` is a string naming the
- charset to be used to encode the value, ``LANGUAGE`` can usually be set
- to ``None`` or the empty string (see :rfc:`2231` for other possibilities),
- and ``VALUE`` is the string value containing non-ASCII code points. If
- a three tuple is not passed and the value contains non-ASCII characters,
- it is automatically encoded in :rfc:`2231` format using a ``CHARSET``
- of ``utf-8`` and a ``LANGUAGE`` of ``None``.
-
- Here's an example::
+ only the key will be added.
+
+ If the value contains non-ASCII characters, the charset and language may
+ be explicitly controlled by specifying the value as a three tuple in the
+ format ``(CHARSET, LANGUAGE, VALUE)``, where ``CHARSET`` is a string
+ naming the charset to be used to encode the value, ``LANGUAGE`` can
+ usually be set to ``None`` or the empty string (see :rfc:`2231` for other
+ possibilities), and ``VALUE`` is the string value containing non-ASCII
+ code points. If a three tuple is not passed and the value contains
+ non-ASCII characters, it is automatically encoded in :rfc:`2231` format
+ using a ``CHARSET`` of ``utf-8`` and a ``LANGUAGE`` of ``None``.
+
+ Here is an example::
msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')
@@ -364,37 +292,35 @@ Here are the methods of the :class:`Message` class:
Content-Disposition: attachment; filename="bud.gif"
- An example with non-ASCII characters::
+ An example of the extended interface with non-ASCII characters::
msg.add_header('Content-Disposition', 'attachment',
filename=('iso-8859-1', '', 'Fußballer.ppt'))
- Which produces ::
-
- Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"
-
.. method:: replace_header(_name, _value)
Replace a header. Replace the first header found in the message that
- matches *_name*, retaining header order and field name case. If no
- matching header was found, a :exc:`KeyError` is raised.
+ matches *_name*, retaining header order and field name case of the
+ original header. If no matching header is found, raise a
+ :exc:`KeyError`.
.. method:: get_content_type()
- Return the message's content type. The returned string is coerced to
- lower case of the form :mimetype:`maintype/subtype`. If there was no
- :mailheader:`Content-Type` header in the message the default type as given
- by :meth:`get_default_type` will be returned. Since according to
- :rfc:`2045`, messages always have a default type, :meth:`get_content_type`
- will always return a value.
+ Return the message's content type, coerced to lower case of the form
+ :mimetype:`maintype/subtype`. If there is no :mailheader:`Content-Type`
+ header in the message return the value returned by
+ :meth:`get_default_type`. If the :mailheader:`Content-Type` header is
+ invalid, return ``text/plain``.
- :rfc:`2045` defines a message's default type to be :mimetype:`text/plain`
- unless it appears inside a :mimetype:`multipart/digest` container, in
- which case it would be :mimetype:`message/rfc822`. If the
- :mailheader:`Content-Type` header has an invalid type specification,
- :rfc:`2045` mandates that the default type be :mimetype:`text/plain`.
+ (According to :rfc:`2045`, messages always have a default type,
+ :meth:`get_content_type` will always return a value. :rfc:`2045` defines
+ a message's default type to be :mimetype:`text/plain` unless it appears
+ inside a :mimetype:`multipart/digest` container, in which case it would
+ be :mimetype:`message/rfc822`. If the :mailheader:`Content-Type` header
+ has an invalid type specification, :rfc:`2045` mandates that the default
+ type be :mimetype:`text/plain`.)
.. method:: get_content_maintype()
@@ -420,81 +346,41 @@ Here are the methods of the :class:`Message` class:
.. method:: set_default_type(ctype)
Set the default content type. *ctype* should either be
- :mimetype:`text/plain` or :mimetype:`message/rfc822`, although this is not
- enforced. The default content type is not stored in the
- :mailheader:`Content-Type` header.
-
-
- .. method:: get_params(failobj=None, header='content-type', unquote=True)
-
- Return the message's :mailheader:`Content-Type` parameters, as a list.
- The elements of the returned list are 2-tuples of key/value pairs, as
- split on the ``'='`` sign. The left hand side of the ``'='`` is the key,
- while the right hand side is the value. If there is no ``'='`` sign in
- the parameter the value is the empty string, otherwise the value is as
- described in :meth:`get_param` and is unquoted if optional *unquote* is
- ``True`` (the default).
-
- Optional *failobj* is the object to return if there is no
- :mailheader:`Content-Type` header. Optional *header* is the header to
- search instead of :mailheader:`Content-Type`.
-
-
- .. method:: get_param(param, failobj=None, header='content-type', unquote=True)
-
- Return the value of the :mailheader:`Content-Type` header's parameter
- *param* as a string. If the message has no :mailheader:`Content-Type`
- header or if there is no such parameter, then *failobj* is returned
- (defaults to ``None``).
-
- Optional *header* if given, specifies the message header to use instead of
- :mailheader:`Content-Type`.
-
- Parameter keys are always compared case insensitively. The return value
- can either be a string, or a 3-tuple if the parameter was :rfc:`2231`
- encoded. When it's a 3-tuple, the elements of the value are of the form
- ``(CHARSET, LANGUAGE, VALUE)``. Note that both ``CHARSET`` and
- ``LANGUAGE`` can be ``None``, in which case you should consider ``VALUE``
- to be encoded in the ``us-ascii`` charset. You can usually ignore
- ``LANGUAGE``.
-
- If your application doesn't care whether the parameter was encoded as in
- :rfc:`2231`, you can collapse the parameter value by calling
- :func:`email.utils.collapse_rfc2231_value`, passing in the return value
- from :meth:`get_param`. This will return a suitably decoded Unicode
- string when the value is a tuple, or the original string unquoted if it
- isn't. For example::
-
- rawparam = msg.get_param('foo')
- param = email.utils.collapse_rfc2231_value(rawparam)
-
- In any case, the parameter value (either the returned string, or the
- ``VALUE`` item in the 3-tuple) is always unquoted, unless *unquote* is set
- to ``False``.
+ :mimetype:`text/plain` or :mimetype:`message/rfc822`, although this is
+ not enforced. The default content type is not stored in the
+ :mailheader:`Content-Type` header, so it only affects the return value of
+ the ``get_content_type`` methods when no :mailheader:`Content-Type`
+ header is present in the message.
.. 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
- *value*. If the :mailheader:`Content-Type` header as not yet been defined
- for this message, it will be set to :mimetype:`text/plain` and the new
- parameter value will be appended as per :rfc:`2045`.
-
- Optional *header* specifies an alternative header to
- :mailheader:`Content-Type`, and all parameters will be quoted as necessary
- unless optional *requote* is ``False`` (the default is ``True``).
-
- If optional *charset* is specified, the parameter will be encoded
- according to :rfc:`2231`. Optional *language* specifies the RFC 2231
- language, defaulting to the empty string. Both *charset* and *language*
- should be strings.
+ parameter already exists in the header, replace its value with *value*.
+ When *header* is ``Content-Type`` (the default) and the header does not
+ yet exist in the message, add it, set its value to
+ :mimetype:`text/plain`, and append the new parameter value. Optional
+ *header* specifies an alternative header to :mailheader:`Content-Type`.
+
+ If the value contains non-ASCII characters, the charset and language may
+ be explicity specified using the optional *charset* and *language*
+ parameters. Optional *language* specifies the :rfc:`2231` language,
+ defaulting to the empty string. Both *charset* and *language* should be
+ strings. The default is to use the ``utf8`` *charset* and ``None`` for
+ the *language*.
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.
+ Use of the *requote* parameter with :class:`EmailMessage` objects is
+ deprecated.
+
+ Note that existing parameter values of headers may be accessed through
+ the :attr:`~email.headerregistry.BaseHeader.params` attribute of the
+ header value (for example, ``msg['Content-Type'].params['charset']``.
+
.. versionchanged:: 3.4 ``replace`` keyword was added.
@@ -502,25 +388,11 @@ Here are the methods of the :class:`Message` class:
Remove the given parameter completely from the :mailheader:`Content-Type`
header. The header will be re-written in place without the parameter or
- its value. All values will be quoted as necessary unless *requote* is
- ``False`` (the default is ``True``). Optional *header* specifies an
- alternative to :mailheader:`Content-Type`.
-
-
- .. method:: set_type(type, header='Content-Type', requote=True)
-
- Set the main type and subtype for the :mailheader:`Content-Type`
- header. *type* must be a string in the form :mimetype:`maintype/subtype`,
- otherwise a :exc:`ValueError` is raised.
-
- This method replaces the :mailheader:`Content-Type` header, keeping all
- the parameters in place. If *requote* is ``False``, this leaves the
- existing header's quoting as is, otherwise the parameters will be quoted
- (the default).
+ its value. Optional *header* specifies an alternative to
+ :mailheader:`Content-Type`.
- An alternative header can be specified in the *header* argument. When the
- :mailheader:`Content-Type` header is set a :mailheader:`MIME-Version`
- header is also added.
+ Use of the *requote* parameter with :class:`EmailMessage` objects is
+ deprecated.
.. method:: get_filename(failobj=None)
@@ -549,12 +421,11 @@ Here are the methods of the :class:`Message` class:
necessary. A :exc:`~email.errors.HeaderParseError` is raised if the
message object has no :mailheader:`Content-Type` header.
- Note that using this method is subtly different than deleting the old
+ Note that using this method is subtly different from deleting the old
:mailheader:`Content-Type` header and adding a new one with the new
boundary via :meth:`add_header`, because :meth:`set_boundary` preserves
the order of the :mailheader:`Content-Type` header in the list of
- headers. However, it does *not* preserve any continuation lines which may
- have been present in the original :mailheader:`Content-Type` header.
+ headers.
.. method:: get_content_charset(failobj=None)
@@ -563,9 +434,6 @@ Here are the methods of the :class:`Message` class:
coerced to lower case. If there is no :mailheader:`Content-Type` header, or if
that header has no ``charset`` parameter, *failobj* is returned.
- Note that this method differs from :meth:`get_charset` which returns the
- :class:`~email.charset.Charset` instance for the default encoding of the message body.
-
.. method:: get_charsets(failobj=None)
@@ -575,10 +443,19 @@ Here are the methods of the :class:`Message` class:
Each item in the list will be a string which is the value of the
``charset`` parameter in the :mailheader:`Content-Type` header for the
- represented subpart. However, if the subpart has no
- :mailheader:`Content-Type` header, no ``charset`` parameter, or is not of
- the :mimetype:`text` main MIME type, then that item in the returned list
- will be *failobj*.
+ represented subpart. If the subpart has no :mailheader:`Content-Type`
+ header, no ``charset`` parameter, or is not of the :mimetype:`text` main
+ MIME type, then that item in the returned list will be *failobj*.
+
+
+ .. method:: is_attachment
+
+ Return ``True`` if there is a :mailheader:`Content-Disposition` header
+ and its (case insensitive) value is ``attachment``, ``False`` otherwise.
+
+ .. versionchanged:: 3.4.2
+ is_attachment is now a method instead of a property, for consistency
+ with :meth:`~email.message.Message.is_multipart`.
.. method:: get_content_disposition()
@@ -590,6 +467,11 @@ Here are the methods of the :class:`Message` class:
.. versionadded:: 3.5
+
+ The following methods relate to interrogating and manipulating the content
+ (payload) of the message.
+
+
.. method:: walk()
The :meth:`walk` method is an all-purpose generator which can be used to
@@ -651,8 +533,169 @@ Here are the methods of the :class:`Message` class:
into the subparts.
- :class:`Message` objects can also optionally contain two instance attributes,
- which can be used when generating the plain text of a MIME message.
+ .. 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 immediate sub-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.EmailMessage.walk`.)
+
+
+ .. method:: get_content(*args, content_manager=None, **kw)
+
+ Call the :meth:`~email.contentmanager.ContentManager.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 :meth:`~email.contentmanager.ContentManager.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:`EmailMessage` objects have the following instance attributes:
.. attribute:: preamble
@@ -682,11 +725,8 @@ Here are the methods of the :class:`Message` class:
The *epilogue* attribute acts the same way as the *preamble* attribute,
except that it contains text that appears between the last boundary and
- the end of the message.
-
- You do not need to set the epilogue to the empty string in order for the
- :class:`~email.generator.Generator` to print a newline at the end of the
- file.
+ the end of the message. As with the :attr:`~EmailMessage.preamble`,
+ if there is no epilog text this attribute will be ``None``.
.. attribute:: defects
@@ -694,3 +734,18 @@ Here are the methods of the :class:`Message` class:
The *defects* attribute contains a list of all the problems found when
parsing this message. See :mod:`email.errors` for a detailed description
of the possible parsing defects.
+
+
+.. 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.
+
+
+.. rubric:: Footnotes
+
+.. [1] Oringally added in 3.4 as a :term:`provisional module <provisional
+ package>`. Docs for legacy message class moved to
+ :ref:`compat32_message`.