From 860711f22a11f1f1bce25b24aad02a56bbdc2dbb Mon Sep 17 00:00:00 2001 From: Matthieu Caneill Date: Sat, 22 Jul 2023 14:32:44 +0200 Subject: [PATCH] Use lowercase `mail from` and `rcpt to` in `smtplib.SMTP` SMTP commands are case-insensitive. `smtplib` uses lowercase commands, however it writes `mail FROM` and `rcpt TO`, lacking consistency. --- Lib/smtplib.py | 4 ++-- Lib/test/test_smtplib.py | 14 ++++++++++++++ .../2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 18c91746fd7bf2..b3cc68a789a7d8 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -542,7 +542,7 @@ def mail(self, sender, options=()): raise SMTPNotSupportedError( 'SMTPUTF8 not supported by server') optionlist = ' ' + ' '.join(options) - self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist)) + self.putcmd("mail", "from:%s%s" % (quoteaddr(sender), optionlist)) return self.getreply() def rcpt(self, recip, options=()): @@ -550,7 +550,7 @@ def rcpt(self, recip, options=()): optionlist = '' if options and self.does_esmtp: optionlist = ' ' + ' '.join(options) - self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist)) + self.putcmd("rcpt", "to:%s%s" % (quoteaddr(recip), optionlist)) return self.getreply() def data(self, msg): diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index b6d5b8c3d82580..f2e02dab1c3ca5 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -831,6 +831,7 @@ class SimSMTPChannel(smtpd.SMTPChannel): def __init__(self, extra_features, *args, **kw): self._extrafeatures = ''.join( [ "250-{0}\r\n".format(x) for x in extra_features ]) + self.all_received_lines = [] super(SimSMTPChannel, self).__init__(*args, **kw) # AUTH related stuff. It would be nice if support for this were in smtpd. @@ -845,6 +846,7 @@ def found_terminator(self): self.smtp_state = self.COMMAND self.push('%s %s' % (e.smtp_code, e.smtp_error)) return + self.all_received_lines.append(self.received_lines) super().found_terminator() @@ -1349,6 +1351,18 @@ def test_name_field_not_included_in_envelop_addresses(self): self.assertEqual(self.serv._addresses['from'], 'michael@example.com') self.assertEqual(self.serv._addresses['tos'], ['rene@example.com']) + def test_lowercase_mail_from_rcpt_to(self): + m = 'A test message' + smtp = smtplib.SMTP( + HOST, self.port, local_hostname='localhost', + timeout=support.LOOPBACK_TIMEOUT) + self.addCleanup(smtp.close) + + smtp.sendmail('John', 'Sally', m) + + self.assertIn(['mail from: size=14'], self.serv._SMTPchannel.all_received_lines) + self.assertIn(['rcpt to:'], self.serv._SMTPchannel.all_received_lines) + class SimSMTPUTF8Server(SimSMTPServer): diff --git a/Misc/NEWS.d/next/Library/2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst b/Misc/NEWS.d/next/Library/2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst new file mode 100644 index 00000000000000..e75b6c0f1d6759 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst @@ -0,0 +1 @@ +Use lowercase ``mail from`` and ``rcpt to`` in :class:`smptlib.SMTP`.