]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-70039: smtplib: store the server name in ._host in .connect() (#115259)
authornmartensen <nis.martensen@web.de>
Wed, 8 Apr 2026 21:46:25 +0000 (23:46 +0200)
committerGitHub <noreply@github.com>
Wed, 8 Apr 2026 21:46:25 +0000 (17:46 -0400)
Original patch by gigaplastik, extended with a few more tests.

Addresses gh-70039 and bpo-25852: failure of starttls if connect is called explicitly.

Lib/smtplib.py
Lib/test/test_smtpnet.py
Misc/NEWS.d/next/Library/2024-02-10-21-25-22.gh-issue-70039.6wvcAP.rst [new file with mode: 0644]

index 72093f7f8b0f2dd6650780e22380bf6bf23a146a..4cfc2338d99c67e4a47c9b3e94163963be97c31b 100644 (file)
@@ -251,7 +251,6 @@ class SMTP:
         will be used.
 
         """
-        self._host = host
         self.timeout = timeout
         self.esmtp_features = {}
         self.command_encoding = 'ascii'
@@ -342,6 +341,7 @@ class SMTP:
                     port = int(port)
                 except ValueError:
                     raise OSError("nonnumeric port")
+        self._host = host
         if not port:
             port = self.default_port
         sys.audit("smtplib.connect", self, host, port)
index d765746987bc4b039066fd0e1828e1a231756232..861e7e6a725c40751ffc4dac5e378c68397fb7af 100644 (file)
@@ -45,6 +45,59 @@ class SmtpTest(unittest.TestCase):
             server.ehlo()
             server.quit()
 
+    def test_connect_host_port_starttls(self):
+        support.get_attribute(smtplib, 'SMTP_SSL')
+        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+        context.check_hostname = False
+        context.verify_mode = ssl.CERT_NONE
+        with socket_helper.transient_internet(self.testServer):
+            server = smtplib.SMTP(f'{self.testServer}:{self.remotePort}')
+            try:
+                server.starttls(context=context)
+            except smtplib.SMTPException as e:
+                if e.args[0] == 'STARTTLS extension not supported by server.':
+                    unittest.skip(e.args[0])
+                else:
+                    raise
+            server.ehlo()
+            server.quit()
+
+    def test_explicit_connect_starttls(self):
+        support.get_attribute(smtplib, 'SMTP_SSL')
+        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+        context.check_hostname = False
+        context.verify_mode = ssl.CERT_NONE
+        with socket_helper.transient_internet(self.testServer):
+            server = smtplib.SMTP()
+            server.connect(self.testServer, self.remotePort)
+            try:
+                server.starttls(context=context)
+            except smtplib.SMTPException as e:
+                if e.args[0] == 'STARTTLS extension not supported by server.':
+                    unittest.skip(e.args[0])
+                else:
+                    raise
+            server.ehlo()
+            server.quit()
+
+    def test_explicit_connect_host_port_starttls(self):
+        support.get_attribute(smtplib, 'SMTP_SSL')
+        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+        context.check_hostname = False
+        context.verify_mode = ssl.CERT_NONE
+        with socket_helper.transient_internet(self.testServer):
+            server = smtplib.SMTP()
+            server.connect(f'{self.testServer}:{self.remotePort}')
+            try:
+                server.starttls(context=context)
+            except smtplib.SMTPException as e:
+                if e.args[0] == 'STARTTLS extension not supported by server.':
+                    unittest.skip(e.args[0])
+                else:
+                    raise
+            server.ehlo()
+            server.quit()
+
 
 class SmtpSSLTest(unittest.TestCase):
     testServer = SMTP_TEST_SERVER
diff --git a/Misc/NEWS.d/next/Library/2024-02-10-21-25-22.gh-issue-70039.6wvcAP.rst b/Misc/NEWS.d/next/Library/2024-02-10-21-25-22.gh-issue-70039.6wvcAP.rst
new file mode 100644 (file)
index 0000000..8bb2cd1
--- /dev/null
@@ -0,0 +1 @@
+Fixed bug where :meth:`smtplib.SMTP.starttls` could fail if :meth:`smtplib.SMTP.connect` is called explicitly rather than implicitly.