diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 4cfc2338d99c67..2c771563ce6b40 100644 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -989,6 +989,11 @@ def send_message(self, msg, from_addr=None, to_addrs=None, def close(self): """Close the connection to the SMTP server.""" + # A new EHLO is required after reconnecting with connect() + self.ehlo_resp = self.helo_resp = None + self.esmtp_features = {} + self.does_esmtp = False + try: file = self.file self.file = None @@ -1003,10 +1008,6 @@ def close(self): def quit(self): """Terminate the SMTP session.""" res = self.docmd("quit") - # A new EHLO is required after reconnecting with connect() - self.ehlo_resp = self.helo_resp = None - self.esmtp_features = {} - self.does_esmtp = False self.close() return res diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index b8aac8c20202a2..c9588da8326b74 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -1265,6 +1265,40 @@ def test_quit_resets_greeting(self): self.assertIn('size', smtp.esmtp_features) smtp.quit() + def test_close_resets_greeting(self): + smtp = smtplib.SMTP(HOST, self.port, + local_hostname='localhost', + timeout=support.LOOPBACK_TIMEOUT) + code, _ = smtp.ehlo() + self.assertEqual(code, 250) + self.assertIn('size', smtp.esmtp_features) + smtp.close() + self.assertNotIn('size', smtp.esmtp_features) + smtp.connect(HOST, self.port) + self.assertNotIn('size', smtp.esmtp_features) + smtp.ehlo_or_helo_if_needed() + self.assertIn('size', smtp.esmtp_features) + smtp.quit() + + def test_with_statement_resets_greeting(self): + with smtplib.SMTP(HOST, self.port, + local_hostname='localhost', + timeout=support.LOOPBACK_TIMEOUT) as smtp: + smtp.ehlo() + self.assertIn('size', smtp.esmtp_features) + + self.assertNotIn('size', smtp.esmtp_features) + + msg = EmailMessage() + msg['From'] = 'test_from' + msg['To'] = 'test_to' + msg['Subject'] = 'test_subject' + + smtp.connect(HOST, self.port) + smtp.send_message(msg) + self.assertIn('size', smtp.esmtp_features) + smtp.quit() + def test_with_statement(self): with smtplib.SMTP(HOST, self.port) as smtp: code, message = smtp.noop() diff --git a/Misc/NEWS.d/next/Library/2026-11-03-15-04-43.gh-issue-48392.DNjjZT.rst b/Misc/NEWS.d/next/Library/2026-11-03-15-04-43.gh-issue-48392.DNjjZT.rst new file mode 100644 index 00000000000000..91a089c2e7a513 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-11-03-15-04-43.gh-issue-48392.DNjjZT.rst @@ -0,0 +1,3 @@ +Fix :meth:`!smtplib.SMTP.close` not resetting the EHLO state, so an +:class:`!SMTP` object reconnected with :meth:`~smtplib.SMTP.connect` sent +``MAIL FROM`` without a new EHLO.