Merge #18584: make doctest examples in email documentation pass.
This commit is contained in:
commit
299a221940
|
@ -33,14 +33,22 @@ useful higher level iterations over message object trees.
|
|||
Thus, by default :func:`typed_subpart_iterator` returns each subpart that has a
|
||||
MIME type of :mimetype:`text/\*`.
|
||||
|
||||
|
||||
The following function has been added as a useful debugging tool. It should
|
||||
*not* be considered part of the supported public interface for the package.
|
||||
|
||||
|
||||
.. function:: _structure(msg, fp=None, level=0, include_default=False)
|
||||
|
||||
Prints an indented representation of the content types of the message object
|
||||
structure. For example::
|
||||
structure. For example:
|
||||
|
||||
.. testsetup::
|
||||
|
||||
>>> import email
|
||||
>>> from email.iterators import _structure
|
||||
>>> somefile = open('Lib/test/test_email/data/msg_02.txt')
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> msg = email.message_from_file(somefile)
|
||||
>>> _structure(msg)
|
||||
|
@ -60,6 +68,10 @@ The following function has been added as a useful debugging tool. It should
|
|||
text/plain
|
||||
text/plain
|
||||
|
||||
.. testcleanup::
|
||||
|
||||
>>> somefile.close()
|
||||
|
||||
Optional *fp* is a file-like object to print the output to. It must be
|
||||
suitable for Python's :func:`print` function. *level* is used internally.
|
||||
*include_default*, if true, prints the default type as well.
|
||||
|
|
|
@ -513,16 +513,25 @@ Here are the methods of the :class:`Message` class:
|
|||
iterator in a ``for`` loop; each iteration returns the next subpart.
|
||||
|
||||
Here's an example that prints the MIME type of every part of a multipart
|
||||
message structure::
|
||||
message structure:
|
||||
|
||||
>>> for part in msg.walk():
|
||||
... print(part.get_content_type())
|
||||
multipart/report
|
||||
text/plain
|
||||
message/delivery-status
|
||||
text/plain
|
||||
text/plain
|
||||
message/rfc822
|
||||
.. testsetup::
|
||||
|
||||
>>> from email import message_from_binary_file
|
||||
>>> with open('Lib/test/test_email/data/msg_16.txt', 'rb') as f:
|
||||
... msg = message_from_binary_file(f)
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> for part in msg.walk():
|
||||
... print(part.get_content_type())
|
||||
multipart/report
|
||||
text/plain
|
||||
message/delivery-status
|
||||
text/plain
|
||||
text/plain
|
||||
message/rfc822
|
||||
text/plain
|
||||
|
||||
:class:`Message` objects can also optionally contain two instance attributes,
|
||||
which can be used when generating the plain text of a MIME message.
|
||||
|
|
|
@ -56,19 +56,42 @@ same keyword arguments as the class constructor and returning a new
|
|||
attributes values changed.
|
||||
|
||||
As an example, the following code could be used to read an email message from a
|
||||
file on disk and pass it to the system ``sendmail`` program on a Unix system::
|
||||
file on disk and pass it to the system ``sendmail`` program on a Unix system:
|
||||
|
||||
>>> from email import msg_from_binary_file
|
||||
.. testsetup::
|
||||
|
||||
>>> from unittest import mock
|
||||
>>> mocker = mock.patch('subprocess.Popen')
|
||||
>>> m = mocker.start()
|
||||
>>> proc = mock.MagicMock()
|
||||
>>> m.return_value = proc
|
||||
>>> proc.stdin.close.return_value = None
|
||||
>>> mymsg = open('mymsg.txt', 'w')
|
||||
>>> mymsg.write('To: abc@xyz.com\n\n')
|
||||
17
|
||||
>>> mymsg.flush()
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> from email import message_from_binary_file
|
||||
>>> from email.generator import BytesGenerator
|
||||
>>> from email import policy
|
||||
>>> from subprocess import Popen, PIPE
|
||||
>>> with open('mymsg.txt', 'b') as f:
|
||||
... msg = msg_from_binary_file(f)
|
||||
>>> p = Popen(['sendmail', msg['To'][0].address], stdin=PIPE)
|
||||
>>> with open('mymsg.txt', 'rb') as f:
|
||||
... msg = message_from_binary_file(f, policy=policy.default)
|
||||
>>> p = Popen(['sendmail', msg['To'].addresses[0]], stdin=PIPE)
|
||||
>>> g = BytesGenerator(p.stdin, policy=msg.policy.clone(linesep='\r\n'))
|
||||
>>> g.flatten(msg)
|
||||
>>> p.stdin.close()
|
||||
>>> rc = p.wait()
|
||||
|
||||
.. testcleanup::
|
||||
|
||||
>>> mymsg.close()
|
||||
>>> mocker.stop()
|
||||
>>> import os
|
||||
>>> os.remove('mymsg.txt')
|
||||
|
||||
Here we are telling :class:`~email.generator.BytesGenerator` to use the RFC
|
||||
correct line separator characters when creating the binary string to feed into
|
||||
``sendmail's`` ``stdin``, where the default policy would use ``\n`` line
|
||||
|
@ -82,22 +105,22 @@ separators for the platform on which it is running::
|
|||
|
||||
>>> import os
|
||||
>>> with open('converted.txt', 'wb') as f:
|
||||
... f.write(msg.as_string(policy=msg.policy.clone(linesep=os.linesep))
|
||||
... f.write(msg.as_string(policy=msg.policy.clone(linesep=os.linesep)))
|
||||
|
||||
Policy objects can also be combined using the addition operator, producing a
|
||||
policy object whose settings are a combination of the non-default values of the
|
||||
summed objects::
|
||||
|
||||
>>> compat_SMTP = email.policy.clone(linesep='\r\n')
|
||||
>>> compat_strict = email.policy.clone(raise_on_defect=True)
|
||||
>>> compat_SMTP = policy.compat32.clone(linesep='\r\n')
|
||||
>>> compat_strict = policy.compat32.clone(raise_on_defect=True)
|
||||
>>> compat_strict_SMTP = compat_SMTP + compat_strict
|
||||
|
||||
This operation is not commutative; that is, the order in which the objects are
|
||||
added matters. To illustrate::
|
||||
|
||||
>>> policy100 = compat32.clone(max_line_length=100)
|
||||
>>> policy80 = compat32.clone(max_line_length=80)
|
||||
>>> apolicy = policy100 + Policy80
|
||||
>>> policy100 = policy.compat32.clone(max_line_length=100)
|
||||
>>> policy80 = policy.compat32.clone(max_line_length=80)
|
||||
>>> apolicy = policy100 + policy80
|
||||
>>> apolicy.max_line_length
|
||||
80
|
||||
>>> apolicy = policy80 + policy100
|
||||
|
|
Loading…
Reference in New Issue