diff options
Diffstat (limited to 'Doc/library/email.message.rst')
-rw-r--r-- | Doc/library/email.message.rst | 719 |
1 files changed, 387 insertions, 332 deletions
diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 2907975357..95136d2b84 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 specifing 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`. |