https://github.com/python/cpython/commit/6a1a23f2e79617e5d7ef3ce141105f9f9fc50b10
commit: 6a1a23f2e79617e5d7ef3ce141105f9f9fc50b10
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-07-02T07:46:30Z
summary:

[3.15] gh-108280: Give a meaningful error for an invalid imaplib greeting 
(GH-152768) (GH-152856)

Connecting to a server that does not send a valid IMAP4 greeting, such as
a POP3 server answering on the IMAP port, failed with the unhelpful
"imaplib.IMAP4.error: None".  A meaningful message is now raised instead.
(cherry picked from commit 262b6a0df5a325e788928ab0cd514fa4786571b4)

Co-authored-by: Serhiy Storchaka <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-07-01-12-00-00.gh-issue-108280.Nq8vTr.rst
M Lib/imaplib.py
M Lib/test/test_imaplib.py

diff --git a/Lib/imaplib.py b/Lib/imaplib.py
index 26773fb0ee083b..ca2ae40726b2d1 100644
--- a/Lib/imaplib.py
+++ b/Lib/imaplib.py
@@ -253,7 +253,11 @@ def _connect(self):
         elif 'OK' in self.untagged_responses:
             self.state = 'NONAUTH'
         else:
-            raise self.error(self.welcome)
+            # A continuation ('+') greeting is returned as None; report its
+            # raw line, still held by the last match (gh-108280).
+            greeting = (self.welcome or self.mo.string).decode(
+                self._encoding, 'replace')
+            raise self.error('invalid greeting: ' + greeting)
 
         self._refresh_capabilities()
         if __debug__:
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
index fa23d09806e6fb..67bf47ad41a1ac 100644
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -331,6 +331,39 @@ def handle(self):
         self.assertRaises(imaplib.IMAP4.abort, self.imap_class,
                           *server.server_address)
 
+    def test_invalid_greeting(self):
+        # An invalid greeting, e.g. from a POP3 server on the IMAP port,
+        # must not fail with "error: None" but report the server's line
+        # (gh-108280).
+        class Pop3Handler(socketserver.StreamRequestHandler):
+            def handle(self):
+                self.wfile.write(b'+OK POP3 server ready\r\n')
+        _, server = self._setup(Pop3Handler, connect=False)
+        with self.assertRaisesRegex(imaplib.IMAP4.error,
+                                    r'invalid greeting: \+OK POP3 server 
ready'):
+            self.imap_class(*server.server_address)
+
+    def test_invalid_greeting_untagged(self):
+        # An untagged greeting that is neither OK nor PREAUTH (e.g. BYE)
+        # is reported as is (gh-108280).
+        class ByeHandler(socketserver.StreamRequestHandler):
+            def handle(self):
+                self.wfile.write(b'* BYE Server unavailable\r\n')
+        _, server = self._setup(ByeHandler, connect=False)
+        with self.assertRaisesRegex(imaplib.IMAP4.error,
+                                    r'invalid greeting: \* BYE Server 
unavailable'):
+            self.imap_class(*server.server_address)
+
+    def test_invalid_greeting_bare_continuation(self):
+        # A bare continuation greeting is still reported (gh-108280).
+        class BareHandler(socketserver.StreamRequestHandler):
+            def handle(self):
+                self.wfile.write(b'+\r\n')
+        _, server = self._setup(BareHandler, connect=False)
+        with self.assertRaisesRegex(imaplib.IMAP4.error,
+                                    r'invalid greeting: \+'):
+            self.imap_class(*server.server_address)
+
     def test_line_termination(self):
         class BadNewlineHandler(SimpleIMAPHandler):
             def cmd_CAPABILITY(self, tag, args):
diff --git 
a/Misc/NEWS.d/next/Library/2026-07-01-12-00-00.gh-issue-108280.Nq8vTr.rst 
b/Misc/NEWS.d/next/Library/2026-07-01-12-00-00.gh-issue-108280.Nq8vTr.rst
new file mode 100644
index 00000000000000..487c9da67f1832
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-07-01-12-00-00.gh-issue-108280.Nq8vTr.rst
@@ -0,0 +1,4 @@
+Connecting :mod:`imaplib` to a server that does not send a valid IMAP4
+greeting (for example a POP3 server answering on the IMAP port) now raises
+an error reporting the server's response instead of
+``imaplib.IMAP4.error: None``.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to