diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 3dd67b2a2aba97..29c979b53a6720 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1538,6 +1538,31 @@ def testSetSockOpt(self): reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) self.assertFalse(reuse == 0, "failed to set reuse mode") + @unittest.skipIf(_testcapi is None, "requires _testcapi") + def test_setsockopt_errors(self): + # See issue #107546. + from _testcapi import INT_MAX, INT_MIN + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.addCleanup(sock.close) + + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # No error expected. + + with self.assertRaises(OverflowError): + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, INT_MAX + 1) + + with self.assertRaises(OverflowError): + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, INT_MIN - 1) + + with self.assertRaises(OverflowError): + sock.setsockopt(socket.SOL_SOCKET, INT_MAX + 1, 1) + + with self.assertRaises(OverflowError): + sock.setsockopt(INT_MAX + 1, socket.SO_REUSEADDR, 1) + + with self.assertRaises(TypeError): + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, dict()) + def testSendAfterClose(self): # testing send() after close() with timeout with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-24-00-21-27.gh-issue-107545.GDa7Zs.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-24-00-21-27.gh-issue-107545.GDa7Zs.rst new file mode 100644 index 00000000000000..3dc853987e0e0b --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-24-00-21-27.gh-issue-107545.GDa7Zs.rst @@ -0,0 +1,2 @@ +Improve error message when :meth:`~socket.socket.setsockopt` raises an error +other than a :exc:`TypeError`. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index f3ad01854de93b..25e1e465926c5c 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3373,6 +3373,9 @@ sock_setsockopt(PyObject *self, PyObject *args) (char*)&flag, sizeof flag); goto done; } + if (!PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } PyErr_Clear(); /* setsockopt(level, opt, None, flag) */ @@ -3383,6 +3386,9 @@ sock_setsockopt(PyObject *self, PyObject *args) NULL, (socklen_t)optlen); goto done; } + if (!PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } PyErr_Clear(); /* setsockopt(level, opt, buffer) */