]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-100218: correctly set `errno` when `socket.if_{nametoindex,indextoname...
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>
Sun, 9 Nov 2025 13:31:49 +0000 (14:31 +0100)
committerGitHub <noreply@github.com>
Sun, 9 Nov 2025 13:31:49 +0000 (13:31 +0000)
Previously, socket.if_nametoindex() and socket.if_indextoname() could raise
an `OSError` with a `None` errno. Now, the errno from libc is propagated.

(cherry picked from commit 3ce2d57b2f02030353af314d89c5f6215d2f5c96)

Lib/test/test_socket.py
Misc/NEWS.d/next/Library/2025-11-02-11-46-00.gh-issue-100218.9Ezfdq.rst [new file with mode: 0644]
Modules/socketmodule.c

index 24b1fe3a443a874b90e31fb1d7c66c169c5306ac..dc104958588f91371e0a2b5cd62792baf132fbda 100644 (file)
@@ -1167,7 +1167,10 @@ class GeneralModuleTests(unittest.TestCase):
     @unittest.skipUnless(hasattr(socket, 'if_indextoname'),
                          'socket.if_indextoname() not available.')
     def testInvalidInterfaceIndexToName(self):
-        self.assertRaises(OSError, socket.if_indextoname, 0)
+        with self.assertRaises(OSError) as cm:
+            socket.if_indextoname(0)
+        self.assertIsNotNone(cm.exception.errno)
+
         self.assertRaises(OverflowError, socket.if_indextoname, -1)
         self.assertRaises(OverflowError, socket.if_indextoname, 2**1000)
         self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF')
@@ -1186,8 +1189,11 @@ class GeneralModuleTests(unittest.TestCase):
     @unittest.skipUnless(hasattr(socket, 'if_nametoindex'),
                          'socket.if_nametoindex() not available.')
     def testInvalidInterfaceNameToIndex(self):
+        with self.assertRaises(OSError) as cm:
+            socket.if_nametoindex("_DEADBEEF")
+        self.assertIsNotNone(cm.exception.errno)
+
         self.assertRaises(TypeError, socket.if_nametoindex, 0)
-        self.assertRaises(OSError, socket.if_nametoindex, '_DEADBEEF')
 
     @unittest.skipUnless(hasattr(sys, 'getrefcount'),
                          'test needs sys.getrefcount()')
diff --git a/Misc/NEWS.d/next/Library/2025-11-02-11-46-00.gh-issue-100218.9Ezfdq.rst b/Misc/NEWS.d/next/Library/2025-11-02-11-46-00.gh-issue-100218.9Ezfdq.rst
new file mode 100644 (file)
index 0000000..2f7500d
--- /dev/null
@@ -0,0 +1,3 @@
+Correctly set :attr:`~OSError.errno` when :func:`socket.if_nametoindex` or
+:func:`socket.if_indextoname` raise an :exc:`OSError`. Patch by Bénédikt
+Tran.
index af7f81701b01aa8f3c7f775afa8abd3b6f2ff0c3..edc79c9d3b878c1c5e9690d9dc1923ddfd3aee85 100644 (file)
@@ -7114,10 +7114,10 @@ _socket_socket_if_nametoindex_impl(PySocketSockObject *self, PyObject *oname)
     unsigned long index;
 #endif
 
+    errno = ENODEV;  // in case 'if_nametoindex' does not set errno
     index = if_nametoindex(PyBytes_AS_STRING(oname));
     if (index == 0) {
-        /* if_nametoindex() doesn't set errno */
-        PyErr_SetString(PyExc_OSError, "no interface with this name");
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
 
@@ -7144,6 +7144,7 @@ socket_if_indextoname(PyObject *self, PyObject *arg)
         return NULL;
     }
 
+    errno = ENXIO;  // in case 'if_indextoname' does not set errno
     char name[IF_NAMESIZE + 1];
     if (if_indextoname(index, name) == NULL) {
         PyErr_SetFromErrno(PyExc_OSError);