]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-122909: Pass ftp error strings to URLError constructor (#122913)
authorJeremy Hylton <32469542+jeremyhylton@users.noreply.github.com>
Tue, 20 Aug 2024 00:35:05 +0000 (20:35 -0400)
committerGitHub <noreply@github.com>
Tue, 20 Aug 2024 00:35:05 +0000 (00:35 +0000)
* pass the original string error message from the ftplib error to URLError()

* Update request.py

Change error string for ftp error to be consistent with other errors reported for ftp

* Add NEWS entry for change to urllib.request for ftp errors.

* Track the change in the ftp error message in the test.

Lib/test/test_urllib2.py
Lib/urllib/request.py
Misc/NEWS.d/next/Library/2024-08-19-17-37-18.gh-issue-122909.kP12SK.rst [new file with mode: 0644]

index eed0599642edfb2fe2572fad8f49bf3a60fe19dd..19179fdc9508ca126a6a653021f4706f92ace424 100644 (file)
@@ -8,6 +8,7 @@ from unittest import mock
 
 import os
 import io
+import ftplib
 import socket
 import array
 import sys
@@ -754,7 +755,6 @@ class HandlerTests(unittest.TestCase):
                 self.ftpwrapper = MockFTPWrapper(self.data)
                 return self.ftpwrapper
 
-        import ftplib
         data = "rheum rhaponicum"
         h = NullFTPHandler(data)
         h.parent = MockOpener()
@@ -794,6 +794,27 @@ class HandlerTests(unittest.TestCase):
             self.assertEqual(headers.get("Content-type"), mimetype)
             self.assertEqual(int(headers["Content-length"]), len(data))
 
+    def test_ftp_error(self):
+        class ErrorFTPHandler(urllib.request.FTPHandler):
+            def __init__(self, exception):
+                self._exception = exception
+
+            def connect_ftp(self, user, passwd, host, port, dirs,
+                            timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
+                raise self._exception
+
+        exception = ftplib.error_perm(
+            "500 OOPS: cannot change directory:/nonexistent")
+        h = ErrorFTPHandler(exception)
+        urlopen = urllib.request.build_opener(h).open
+        try:
+            urlopen("ftp://www.pythontest.net/")
+        except urllib.error.URLError as raised:
+            self.assertEqual(raised.reason,
+                             f"ftp error: {exception.args[0]}")
+        else:
+            self.fail("Did not raise ftplib exception")
+
     def test_file(self):
         import email.utils
         h = urllib.request.FileHandler()
index 58b0cb574a764a6561b59d7a57e28ef46d8537d8..bc35d8a80e5d0399999ead2f84d560522b233ea7 100644 (file)
@@ -1555,7 +1555,7 @@ class FTPHandler(BaseHandler):
             headers = email.message_from_string(headers)
             return addinfourl(fp, headers, req.full_url)
         except ftplib.all_errors as exp:
-            raise URLError(exp) from exp
+            raise URLError(f"ftp error: {exp}") from exp
 
     def connect_ftp(self, user, passwd, host, port, dirs, timeout):
         return ftpwrapper(user, passwd, host, port, dirs, timeout,
diff --git a/Misc/NEWS.d/next/Library/2024-08-19-17-37-18.gh-issue-122909.kP12SK.rst b/Misc/NEWS.d/next/Library/2024-08-19-17-37-18.gh-issue-122909.kP12SK.rst
new file mode 100644 (file)
index 0000000..50eb4af
--- /dev/null
@@ -0,0 +1,3 @@
+In urllib.request when URLError is raised opening an ftp URL, the exception
+argument is now consistently a string. Earlier versions passed either a
+string or an ftplib exception instance as the argument to URLError.