Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 29d1bc0

Browse files
committed
#24277: The new email API is no longer provisional.
This is a wholesale reorganization and editing of the email documentation to make the new API the standard one, and the old API the 'legacy' one. The default is still the compat32 policy, for backward compatibility. We will change that eventually.
1 parent 23e8633 commit 29d1bc0

25 files changed

Lines changed: 2065 additions & 1657 deletions

Doc/includes/email-alternative-new-api.py

Lines changed: 0 additions & 56 deletions
This file was deleted.

Doc/includes/email-alternative.py

100755100644
Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,55 @@
22

33
import smtplib
44

5-
from email.mime.multipart import MIMEMultipart
6-
from email.mime.text import MIMEText
7-
8-
# me == my email address
9-
# you == recipient's email address
10-
11-
12-
13-
# Create message container - the correct MIME type is multipart/alternative.
14-
msg = MIMEMultipart('alternative')
15-
msg['Subject'] = "Link"
16-
msg['From'] = me
17-
msg['To'] = you
18-
19-
# Create the body of the message (a plain-text and an HTML version).
20-
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttps://www.python.org"
21-
html = """\
5+
from email.message import EmailMessage
6+
from email.headerregistry import Address
7+
from email.utils import make_msgid
8+
9+
# Create the base text message.
10+
msg = EmailMessage()
11+
msg['Subject'] = "Ayons asperges pour le déjeuner"
12+
msg['From'] = Address("Pepé Le Pew", "pepe", "example.com")
13+
msg['To'] = (Address("Penelope Pussycat", "penelope", "example.com"),
14+
Address("Fabrette Pussycat", "fabrette", "example.com"))
15+
msg.set_content("""\
16+
Salut!
17+
18+
Cela ressemble à un excellent recipie[1] déjeuner.
19+
20+
[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718
21+
22+
--Pepé
23+
""")
24+
25+
# Add the html version. This converts the message into a multipart/alternative
26+
# container, with the original text message as the first part and the new html
27+
# message as the second part.
28+
asparagus_cid = make_msgid()
29+
msg.add_alternative("""\
2230
<html>
2331
<head></head>
2432
<body>
25-
<p>Hi!<br>
26-
How are you?<br>
27-
Here is the <a href="https://www.python.org">link</a> you wanted.
33+
<p>Salut!<\p>
34+
<p>Cela ressemble à un excellent
35+
<a href="http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718>
36+
recipie
37+
</a> déjeuner.
2838
</p>
39+
<img src="cid:{asparagus_cid}" \>
2940
</body>
3041
</html>
31-
"""
42+
""".format(asparagus_cid=asparagus_cid[1:-1]), subtype='html')
43+
# note that we needed to peel the <> off the msgid for use in the html.
3244

33-
# Record the MIME types of both parts - text/plain and text/html.
34-
part1 = MIMEText(text, 'plain')
35-
part2 = MIMEText(html, 'html')
45+
# Now add the related image to the html part.
46+
with open("roasted-asparagus.jpg", 'rb') as img:
47+
msg.get_payload()[1].add_related(img.read(), 'image', 'jpeg',
48+
cid=asparagus_cid)
3649

37-
# Attach parts into message container.
38-
# According to RFC 2046, the last part of a multipart message, in this case
39-
# the HTML message, is best and preferred.
40-
msg.attach(part1)
41-
msg.attach(part2)
50+
# Make a local copy of what we are going to send.
51+
with open('outgoing.msg', 'wb') as f:
52+
f.write(bytes(msg))
4253

4354
# Send the message via local SMTP server.
44-
s = smtplib.SMTP('localhost')
45-
# sendmail function takes 3 arguments: sender's address, recipient's address
46-
# and message to send - here it is sent as one string.
47-
s.sendmail(me, you, msg.as_string())
48-
s.quit()
55+
with smtplib.SMTP('localhost') as s:
56+
s.send_message(msg)

Doc/includes/email-dir.py

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,14 @@
33
"""Send the contents of a directory as a MIME message."""
44

55
import os
6-
import sys
76
import smtplib
87
# For guessing MIME type based on file name extension
98
import mimetypes
109

1110
from argparse import ArgumentParser
1211

13-
from email import encoders
14-
from email.message import Message
15-
from email.mime.audio import MIMEAudio
16-
from email.mime.base import MIMEBase
17-
from email.mime.image import MIMEImage
18-
from email.mime.multipart import MIMEMultipart
19-
from email.mime.text import MIMEText
20-
21-
COMMASPACE = ', '
12+
from email.message import EmailMessage
13+
from email.policy import SMTP
2214

2315

2416
def main():
@@ -47,12 +39,12 @@ def main():
4739
directory = args.directory
4840
if not directory:
4941
directory = '.'
50-
# Create the enclosing (outer) message
51-
outer = MIMEMultipart()
52-
outer['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)
53-
outer['To'] = COMMASPACE.join(args.recipients)
54-
outer['From'] = args.sender
55-
outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
42+
# Create the message
43+
msg = EmailMessage()
44+
msg['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)
45+
msg['To'] = ', '.join(args.recipients)
46+
msg['From'] = args.sender
47+
msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
5648

5749
for filename in os.listdir(directory):
5850
path = os.path.join(directory, filename)
@@ -67,33 +59,18 @@ def main():
6759
# use a generic bag-of-bits type.
6860
ctype = 'application/octet-stream'
6961
maintype, subtype = ctype.split('/', 1)
70-
if maintype == 'text':
71-
with open(path) as fp:
72-
# Note: we should handle calculating the charset
73-
msg = MIMEText(fp.read(), _subtype=subtype)
74-
elif maintype == 'image':
75-
with open(path, 'rb') as fp:
76-
msg = MIMEImage(fp.read(), _subtype=subtype)
77-
elif maintype == 'audio':
78-
with open(path, 'rb') as fp:
79-
msg = MIMEAudio(fp.read(), _subtype=subtype)
80-
else:
81-
with open(path, 'rb') as fp:
82-
msg = MIMEBase(maintype, subtype)
83-
msg.set_payload(fp.read())
84-
# Encode the payload using Base64
85-
encoders.encode_base64(msg)
86-
# Set the filename parameter
87-
msg.add_header('Content-Disposition', 'attachment', filename=filename)
88-
outer.attach(msg)
62+
with open(path, 'rb') as fp:
63+
msg.add_attachment(fp.read(),
64+
maintype=maintype,
65+
subtype=subtype,
66+
filename=filename)
8967
# Now send or store the message
90-
composed = outer.as_string()
9168
if args.output:
92-
with open(args.output, 'w') as fp:
93-
fp.write(composed)
69+
with open(args.output, 'wb') as fp:
70+
fp.write(msg.as_bytes(policy=SMTP))
9471
else:
9572
with smtplib.SMTP('localhost') as s:
96-
s.sendmail(args.sender, args.recipients, composed)
73+
s.send_message(msg)
9774

9875

9976
if __name__ == '__main__':

Doc/includes/email-headers.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
# Import the email modules we'll need
2-
from email.parser import Parser
2+
from email.parser import BytesParser, Parser
3+
from email.policy import default
34

45
# If the e-mail headers are in a file, uncomment these two lines:
5-
# with open(messagefile) as fp:
6-
# headers = Parser().parse(fp)
6+
# with open(messagefile, 'rb') as fp:
7+
# headers = BytesParser(policy=default).parse(fp)
78

8-
# Or for parsing headers in a string, use:
9-
headers = Parser().parsestr('From: <[email protected]>\n'
9+
# Or for parsing headers in a string (this is an uncommon operation), use:
10+
headers = Parser(policy=default).parsestr(
11+
'From: Foo Bar <[email protected]>\n'
1012
1113
'Subject: Test message\n'
1214
'\n'
1315
'Body would go here\n')
1416

1517
# Now the header items can be accessed as a dictionary:
16-
print('To: %s' % headers['to'])
17-
print('From: %s' % headers['from'])
18-
print('Subject: %s' % headers['subject'])
18+
print('To: {}'.format(headers['to']))
19+
print('From: {}'.format(headers['from']))
20+
print('Subject: {}'.format(headers['subject']))
21+
22+
# You can also access the parts of the addresses:
23+
print('Recipient username: {}'.format(headers['to'].addresses[0].username))
24+
print('Sender name: {}'.format(headers['from'].addresses[0].display_name))

Doc/includes/email-mime.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
# Import smtplib for the actual sending function
22
import smtplib
33

4-
# Here are the email package modules we'll need
5-
from email.mime.image import MIMEImage
6-
from email.mime.multipart import MIMEMultipart
4+
# And imghdr to find the types of our images
5+
import imghdr
76

8-
COMMASPACE = ', '
7+
# Here are the email package modules we'll need
8+
from email.message import EmailMessage
99

10-
# Create the container (outer) email message.
11-
msg = MIMEMultipart()
10+
# Create the container email message.
11+
msg = EmailMessage()
1212
msg['Subject'] = 'Our family reunion'
1313
# me == the sender's email address
1414
# family = the list of all recipients' email addresses
1515
msg['From'] = me
16-
msg['To'] = COMMASPACE.join(family)
16+
msg['To'] = ', '.join(family)
1717
msg.preamble = 'Our family reunion'
1818

19-
# Assume we know that the image files are all in PNG format
19+
# Open the files in binary mode. Use imghdr to figure out the
20+
# MIME subtype for each specific image.
2021
for file in pngfiles:
21-
# Open the files in binary mode. Let the MIMEImage class automatically
22-
# guess the specific image type.
2322
with open(file, 'rb') as fp:
24-
img = MIMEImage(fp.read())
25-
msg.attach(img)
23+
img_data = fp.read()
24+
msg.add_attachment(img_data, maintype='image',
25+
subtype=imghdr.what(None, img_data))
2626

2727
# Send the email via our own SMTP server.
28-
s = smtplib.SMTP('localhost')
29-
s.send_message(msg)
30-
s.quit()
28+
with smtplib.SMTP('localhost') as s:
29+
s.send_message(msg)
File renamed without changes.

Doc/includes/email-simple.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
import smtplib
33

44
# Import the email modules we'll need
5-
from email.mime.text import MIMEText
5+
from email.message import EmailMessage
66

7-
# Open a plain text file for reading. For this example, assume that
8-
# the text file contains only ASCII characters.
7+
# Open the plain text file whose name is in textfile for reading.
98
with open(textfile) as fp:
109
# Create a text/plain message
11-
msg = MIMEText(fp.read())
10+
msg = EmailMessage()
11+
msg.set_content(fp.read())
1212

1313
# me == the sender's email address
1414
# you == the recipient's email address

Doc/includes/email-unpack.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
"""Unpack a MIME message into a directory of files."""
44

55
import os
6-
import sys
76
import email
8-
import errno
97
import mimetypes
108

9+
from email.policy import default
10+
1111
from argparse import ArgumentParser
1212

1313

@@ -22,8 +22,8 @@ def main():
2222
parser.add_argument('msgfile')
2323
args = parser.parse_args()
2424

25-
with open(args.msgfile) as fp:
26-
msg = email.message_from_file(fp)
25+
with open(args.msgfile, 'rb') as fp:
26+
msg = email.message_from_binary_file(fp, policy=default)
2727

2828
try:
2929
os.mkdir(args.directory)

Doc/library/email.charset.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88

99
--------------
1010

11+
This module is part of the legacy (``Compat32``) email API. In the new
12+
API only the aliases table is used.
13+
14+
The remaining text in this section is the original documentation of the module.
15+
1116
This module provides a class :class:`Charset` for representing character sets
1217
and character set conversions in email messages, as well as a character set
1318
registry and several convenience methods for manipulating this registry.

0 commit comments

Comments
 (0)