summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2018-09-08 02:20:27 +0100
committerGitHub <noreply@github.com>2018-09-08 02:20:27 +0100
commiteb6ab73f93c8b883a8d75a83560e2b4c59170d95 (patch)
tree8f26cf42c7bef651024feb3676c001857a228d55 /Lib
parent[3.6] bpo-34007: Skip traceback tests if the Program Counter is not available... (diff)
downloadcpython-eb6ab73f93c8b883a8d75a83560e2b4c59170d95.tar.gz
cpython-eb6ab73f93c8b883a8d75a83560e2b4c59170d95.tar.bz2
cpython-eb6ab73f93c8b883a8d75a83560e2b4c59170d95.zip
[3.6] bpo-34246: Use no mutable default args in smtplib (GH-8554) (#9112)
Some methods of the SMTP class use mutable default arguments. Specially `send_message` is affected as it mutates one of the args by appending items to it, which has side effects on further calls.. (cherry picked from commit d5fbe9b1a3d65ceeb9159c5ba999ee966a945f76) Co-authored-by: Pablo Aguiar <scorphus@gmail.com>
Diffstat (limited to 'Lib')
-rwxr-xr-xLib/smtplib.py12
-rw-r--r--Lib/test/test_smtplib.py32
2 files changed, 38 insertions, 6 deletions
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
index b679875fd2c..048c6bfb067 100755
--- a/Lib/smtplib.py
+++ b/Lib/smtplib.py
@@ -513,7 +513,7 @@ class SMTP:
"""SMTP 'noop' command -- doesn't do anything :>"""
return self.docmd("noop")
- def mail(self, sender, options=[]):
+ def mail(self, sender, options=()):
"""SMTP 'mail' command -- begins mail xfer session.
This method may raise the following exceptions:
@@ -534,7 +534,7 @@ class SMTP:
self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist))
return self.getreply()
- def rcpt(self, recip, options=[]):
+ def rcpt(self, recip, options=()):
"""SMTP 'rcpt' command -- indicates 1 recipient for this mail."""
optionlist = ''
if options and self.does_esmtp:
@@ -785,8 +785,8 @@ class SMTP:
raise SMTPResponseException(resp, reply)
return (resp, reply)
- def sendmail(self, from_addr, to_addrs, msg, mail_options=[],
- rcpt_options=[]):
+ def sendmail(self, from_addr, to_addrs, msg, mail_options=(),
+ rcpt_options=()):
"""This command performs an entire mail transaction.
The arguments are:
@@ -890,7 +890,7 @@ class SMTP:
return senderrs
def send_message(self, msg, from_addr=None, to_addrs=None,
- mail_options=[], rcpt_options={}):
+ mail_options=(), rcpt_options=()):
"""Converts message to a bytestring and passes it to sendmail.
The arguments are as for sendmail, except that msg is an
@@ -958,7 +958,7 @@ class SMTP:
if international:
g = email.generator.BytesGenerator(
bytesmsg, policy=msg.policy.clone(utf8=True))
- mail_options += ['SMTPUTF8', 'BODY=8BITMIME']
+ mail_options = (*mail_options, 'SMTPUTF8', 'BODY=8BITMIME')
else:
g = email.generator.BytesGenerator(bytesmsg)
g.flatten(msg_copy, linesep='\r\n')
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index 79b3bd43687..18110191dc3 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -18,6 +18,11 @@ import textwrap
import unittest
from test import support, mock_socket
+from unittest.mock import Mock
+
+HOST = "localhost"
+HOSTv4 = "127.0.0.1"
+HOSTv6 = "::1"
try:
import threading
@@ -569,6 +574,33 @@ class NonConnectingTests(unittest.TestCase):
"localhost:bogus")
+class DefaultArgumentsTests(unittest.TestCase):
+
+ def setUp(self):
+ self.msg = EmailMessage()
+ self.msg['From'] = 'Páolo <főo@bar.com>'
+ self.smtp = smtplib.SMTP()
+ self.smtp.ehlo = Mock(return_value=(200, 'OK'))
+ self.smtp.has_extn, self.smtp.sendmail = Mock(), Mock()
+
+ def testSendMessage(self):
+ expected_mail_options = ('SMTPUTF8', 'BODY=8BITMIME')
+ self.smtp.send_message(self.msg)
+ self.smtp.send_message(self.msg)
+ self.assertEqual(self.smtp.sendmail.call_args_list[0][0][3],
+ expected_mail_options)
+ self.assertEqual(self.smtp.sendmail.call_args_list[1][0][3],
+ expected_mail_options)
+
+ def testSendMessageWithMailOptions(self):
+ mail_options = ['STARTTLS']
+ expected_mail_options = ('STARTTLS', 'SMTPUTF8', 'BODY=8BITMIME')
+ self.smtp.send_message(self.msg, None, None, mail_options)
+ self.assertEqual(mail_options, ['STARTTLS'])
+ self.assertEqual(self.smtp.sendmail.call_args_list[0][0][3],
+ expected_mail_options)
+
+
# test response of client to a non-successful HELO message
@unittest.skipUnless(threading, 'Threading required for this test.')
class BadHELOServerTests(unittest.TestCase):