Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
8308444e
Kaydet (Commit)
8308444e
authored
May 17, 2015
tarafından
R David Murray
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
#24218: Add SMTPUTF8 support to send_message.
Reviewed by Maciej Szulik.
üst
740d6134
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
86 additions
and
8 deletions
+86
-8
smtplib.rst
Doc/library/smtplib.rst
+10
-2
3.5.rst
Doc/whatsnew/3.5.rst
+4
-2
smtplib.py
Lib/smtplib.py
+26
-3
test_smtplib.py
Lib/test/test_smtplib.py
+46
-1
No files found.
Doc/library/smtplib.rst
Dosyayı görüntüle @
8308444e
...
...
@@ -467,7 +467,7 @@ An :class:`SMTP` instance has the following methods:
If *from_addr* is ``None`` or *to_addrs* is ``None``, ``send_message`` fills
those arguments with addresses extracted from the headers of *msg* as
specified in :rfc:`
28
22`\: *from_addr* is set to the :mailheader:`Sender`
specified in :rfc:`
53
22`\: *from_addr* is set to the :mailheader:`Sender`
field if it is present, and otherwise to the :mailheader:`From` field.
*to_adresses* combines the values (if any) of the :mailheader:`To`,
:mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If exactly one
...
...
@@ -482,10 +482,18 @@ An :class:`SMTP` instance has the following methods:
calls :meth:`sendmail` to transmit the resulting message. Regardless of the
values of *from_addr* and *to_addrs*, ``send_message`` does not transmit any
:mailheader:`Bcc` or :mailheader:`Resent-Bcc` headers that may appear
in *msg*.
in *msg*. If any of the addresses in *from_addr* and *to_addrs* contain
non-ASCII characters and the server does not advertise ``SMTPUTF8`` support,
an :exc:`SMTPNotSupported` error is raised. Otherwise the ``Message`` is
serialized with a clone of its :mod:`~email.policy` with the
:attr:`~email.policy.EmailPolicy.utf8` attribute set to ``True``, and
``SMTPUTF8`` and ``BODY=8BITMIME`` are added to *mail_options*.
.. versionadded:: 3.2
.. versionadded:: 3.5
Support for internationalized addresses (``SMTPUTF8``).
.. method:: SMTP.quit()
...
...
Doc/whatsnew/3.5.rst
Dosyayı görüntüle @
8308444e
...
...
@@ -557,8 +557,10 @@ smtplib
:class:`smtplib.SMTP`. (Contributed by Gavin Chappell and Maciej Szulik in
:issue:`16914`.)
* :mod:`smtplib` now support :rfc:`6531` (SMTPUTF8). (Contributed by
Milan Oberkirch and R. David Murray in :issue:`22027`.)
* :mod:`smtplib` now supports :rfc:`6531` (SMTPUTF8) in both the
:meth:`~smtplib.SMTP.sendmail` and :meth:`~smtplib.SMTP.send_message`
commands. (Contributed by Milan Oberkirch and R. David Murray in
:issue:`22027`.)
sndhdr
------
...
...
Lib/smtplib.py
Dosyayı görüntüle @
8308444e
...
...
@@ -872,7 +872,13 @@ class SMTP:
to_addr, any Bcc field (or Resent-Bcc field, when the Message is a
resent) of the Message object won't be transmitted. The Message
object is then serialized using email.generator.BytesGenerator and
sendmail is called to transmit the message.
sendmail is called to transmit the message. If the sender or any of
the recipient addresses contain non-ASCII and the server advertises the
SMTPUTF8 capability, the policy is cloned with utf8 set to True for the
serialization, and SMTPUTF8 and BODY=8BITMIME are asserted on the send.
If the server does not support SMTPUTF8, an SMPTNotSupported error is
raised. Otherwise the generator is called without modifying the
policy.
"""
# 'Resent-Date' is a mandatory field if the Message is resent (RFC 2822
...
...
@@ -885,6 +891,7 @@ class SMTP:
# option allowing the user to enable the heuristics. (It should be
# possible to guess correctly almost all of the time.)
self
.
ehlo_or_helo_if_needed
()
resent
=
msg
.
get_all
(
'Resent-Date'
)
if
resent
is
None
:
header_prefix
=
''
...
...
@@ -900,14 +907,30 @@ class SMTP:
if
to_addrs
is
None
:
addr_fields
=
[
f
for
f
in
(
msg
[
header_prefix
+
'To'
],
msg
[
header_prefix
+
'Bcc'
],
msg
[
header_prefix
+
'Cc'
])
if
f
is
not
None
]
msg
[
header_prefix
+
'Cc'
])
if
f
is
not
None
]
to_addrs
=
[
a
[
1
]
for
a
in
email
.
utils
.
getaddresses
(
addr_fields
)]
# Make a local copy so we can delete the bcc headers.
msg_copy
=
copy
.
copy
(
msg
)
del
msg_copy
[
'Bcc'
]
del
msg_copy
[
'Resent-Bcc'
]
international
=
False
try
:
''
.
join
([
from_addr
,
*
to_addrs
])
.
encode
(
'ascii'
)
except
UnicodeEncodeError
:
if
not
self
.
has_extn
(
'smtputf8'
):
raise
SMTPNotSupportedError
(
"One or more source or delivery addresses require"
" internationalized email support, but the server"
" does not advertise the required SMTPUTF8 capability"
)
international
=
True
with
io
.
BytesIO
()
as
bytesmsg
:
g
=
email
.
generator
.
BytesGenerator
(
bytesmsg
)
if
international
:
g
=
email
.
generator
.
BytesGenerator
(
bytesmsg
,
policy
=
msg
.
policy
.
clone
(
utf8
=
True
))
mail_options
+=
[
'SMTPUTF8'
,
'BODY=8BITMIME'
]
else
:
g
=
email
.
generator
.
BytesGenerator
(
bytesmsg
)
g
.
flatten
(
msg_copy
,
linesep
=
'
\r\n
'
)
flatmsg
=
bytesmsg
.
getvalue
()
return
self
.
sendmail
(
from_addr
,
to_addrs
,
flatmsg
,
mail_options
,
...
...
Lib/test/test_smtplib.py
Dosyayı görüntüle @
8308444e
import
asyncore
import
email.mime.text
from
email.message
import
EmailMessage
import
email.utils
import
socket
import
smtpd
...
...
@@ -10,7 +11,7 @@ import sys
import
time
import
select
import
errno
import
base64
import
textwrap
import
unittest
from
test
import
support
,
mock_socket
...
...
@@ -1029,6 +1030,8 @@ class SimSMTPUTF8Server(SimSMTPServer):
@unittest.skipUnless
(
threading
,
'Threading required for this test.'
)
class
SMTPUTF8SimTests
(
unittest
.
TestCase
):
maxDiff
=
None
def
setUp
(
self
):
self
.
real_getfqdn
=
socket
.
getfqdn
socket
.
getfqdn
=
mock_socket
.
getfqdn
...
...
@@ -1096,6 +1099,48 @@ class SMTPUTF8SimTests(unittest.TestCase):
self
.
assertIn
(
'SMTPUTF8'
,
self
.
serv
.
last_mail_options
)
self
.
assertEqual
(
self
.
serv
.
last_rcpt_options
,
[])
def
test_send_message_uses_smtputf8_if_addrs_non_ascii
(
self
):
msg
=
EmailMessage
()
msg
[
'From'
]
=
"Páolo <főo@bar.com>"
msg
[
'To'
]
=
'Dinsdale'
msg
[
'Subject'
]
=
'Nudge nudge, wink, wink
\u1F60
9'
# XXX I don't know why I need two \n's here, but this is an existing
# bug (if it is one) and not a problem with the new functionality.
msg
.
set_content
(
"oh là là, know what I mean, know what I mean?
\n\n
"
)
# XXX smtpd converts received /r/n to /n, so we can't easily test that
# we are successfully sending /r/n :(.
expected
=
textwrap
.
dedent
(
"""
\
From: Páolo <főo@bar.com>
To: Dinsdale
Subject: Nudge nudge, wink, wink
\u1F60
9
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
MIME-Version: 1.0
oh là là, know what I mean, know what I mean?
"""
)
smtp
=
smtplib
.
SMTP
(
HOST
,
self
.
port
,
local_hostname
=
'localhost'
,
timeout
=
3
)
self
.
addCleanup
(
smtp
.
close
)
self
.
assertEqual
(
smtp
.
send_message
(
msg
),
{})
self
.
assertEqual
(
self
.
serv
.
last_mailfrom
,
'főo@bar.com'
)
self
.
assertEqual
(
self
.
serv
.
last_rcpttos
,
[
'Dinsdale'
])
self
.
assertEqual
(
self
.
serv
.
last_message
.
decode
(),
expected
)
self
.
assertIn
(
'BODY=8BITMIME'
,
self
.
serv
.
last_mail_options
)
self
.
assertIn
(
'SMTPUTF8'
,
self
.
serv
.
last_mail_options
)
self
.
assertEqual
(
self
.
serv
.
last_rcpt_options
,
[])
def
test_send_message_error_on_non_ascii_addrs_if_no_smtputf8
(
self
):
msg
=
EmailMessage
()
msg
[
'From'
]
=
"Páolo <főo@bar.com>"
msg
[
'To'
]
=
'Dinsdale'
msg
[
'Subject'
]
=
'Nudge nudge, wink, wink
\u1F60
9'
smtp
=
smtplib
.
SMTP
(
HOST
,
self
.
port
,
local_hostname
=
'localhost'
,
timeout
=
3
)
self
.
addCleanup
(
smtp
.
close
)
self
.
assertRaises
(
smtplib
.
SMTPNotSupportedError
,
smtp
.
send_message
(
msg
))
@support.reap_threads
def
test_main
(
verbose
=
None
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment