https://github.com/python/cpython/commit/405f12722cb7631f15d5b6df5825a2262209d9d8
commit: 405f12722cb7631f15d5b6df5825a2262209d9d8
branch: main
author: Andrew Svetlov <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-11-04T11:25:12+05:30
summary:
gh-161076: Ignore setsockopt(TCP_NODELAY) errors in asyncio (#161253)
files:
A Misc/NEWS.d/next/Library/2026-11-03-12-00-00.gh-issue-161076.nOdLy1.rst
M Lib/asyncio/base_events.py
M Lib/test/test_asyncio/test_base_events.py
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 861210775347ae..5d295bc3fb9b5c 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -196,7 +196,13 @@ def _set_nodelay(sock):
if (sock.family in {socket.AF_INET, socket.AF_INET6} and
sock.type == socket.SOCK_STREAM and
sock.proto == socket.IPPROTO_TCP):
- sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+ try:
+ sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+ except OSError:
+ # TCP_NODELAY is only a latency optimization. It can fail
+ # on a connection already reset by the peer (e.g. EINVAL
+ # on macOS); the error will surface on the next I/O.
+ pass
else:
def _set_nodelay(sock):
pass
diff --git a/Lib/test/test_asyncio/test_base_events.py
b/Lib/test/test_asyncio/test_base_events.py
index e11f77ef10c0c9..0c54b64efad7e2 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -2517,6 +2517,17 @@ def test_set_nodelay(self):
sock.setblocking(False)
self.check_set_nodelay(sock)
+ @unittest.skipUnless(hasattr(socket, 'TCP_NODELAY'),
+ 'need socket.TCP_NODELAY')
+ def test_set_nodelay_error(self):
+ # gh-161076: a failing setsockopt() must not break transport creation.
+ sock = mock.Mock(family=socket.AF_INET, type=socket.SOCK_STREAM,
+ proto=socket.IPPROTO_TCP)
+ sock.setsockopt.side_effect = OSError(errno.EINVAL, 'Invalid argument')
+ base_events._set_nodelay(sock)
+ sock.setsockopt.assert_called_once_with(
+ socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+
if __name__ == '__main__':
diff --git
a/Misc/NEWS.d/next/Library/2026-11-03-12-00-00.gh-issue-161076.nOdLy1.rst
b/Misc/NEWS.d/next/Library/2026-11-03-12-00-00.gh-issue-161076.nOdLy1.rst
new file mode 100644
index 00000000000000..bc286d0a676c02
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-11-03-12-00-00.gh-issue-161076.nOdLy1.rst
@@ -0,0 +1,5 @@
+Fix :mod:`asyncio` leaving a half-created transport registered with the
+event loop and the server when setting ``TCP_NODELAY`` on a socket fails.
+Such a failure could make :meth:`asyncio.Server.wait_closed` hang and
+prevent new connections from being served. Errors from
+``setsockopt(TCP_NODELAY)`` are now ignored.
_______________________________________________
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]