diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 84d6d858e7dec1..e79d2e752cf9f3 100644 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -886,7 +886,14 @@ def sendmail(self, from_addr, to_addrs, msg, mail_options=(), # the server refused all our recipients self._rset() raise SMTPRecipientsRefused(senderrs) - (code, resp) = self.data(msg) + try: + (code, resp) = self.data(msg) + except SMTPDataError as ex: + if ex.smtp_code == 421: + self.close() + else: + self._rset() + raise if code != 250: if code == 421: self.close() diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 4c9fc14bd43f54..6a5d9046684859 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -1259,6 +1259,10 @@ def test__rest_from_mail_cmd(self): smtp.sendmail('John', 'Sally', 'test message') self.assertIsNone(smtp.sock) + # The following 421 response tests for sendmail ensure that sendmail handles + # 421 respones correctly by closing the connection. sendmail has to take + # care of this, as it wraps a mail transaction for users. + # Issue 5713: make sure close, not rset, is called if we get a 421 error def test_421_from_mail_cmd(self): smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', @@ -1297,6 +1301,16 @@ def found_terminator(self): self.assertIsNone(smtp.sock) self.assertEqual(self.serv._SMTPchannel.rcpt_count, 0) + def test_421_during_data_cmd(self): + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', + timeout=support.LOOPBACK_TIMEOUT) + smtp.noop() + self.serv._SMTPchannel.data_response = '421 closing' + with self.assertRaises(smtplib.SMTPDataError): + smtp.sendmail('John@foo.org', ['Sally@foo.org'], 'test message') + self.assertIsNone(smtp.sock) + self.assertEqual(self.serv._SMTPchannel.rcpt_count, 0) + def test_smtputf8_NotSupportedError_if_no_server_support(self): smtp = smtplib.SMTP( HOST, self.port, local_hostname='localhost', diff --git a/Misc/NEWS.d/next/Library/2025-05-20-15-39-55.gh-issue-132796.UJXDBR.rst b/Misc/NEWS.d/next/Library/2025-05-20-15-39-55.gh-issue-132796.UJXDBR.rst new file mode 100644 index 00000000000000..fadf346490a85b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-05-20-15-39-55.gh-issue-132796.UJXDBR.rst @@ -0,0 +1,3 @@ +Improve handling of 421 SMTP responses in :meth:`smtplib.SMTP.sendmail` by +covering a previously missing case in which 421 occurs while sending a DATA +command.