diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 04fb961e9985e4..06a00a0656639f 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1131,6 +1131,7 @@ async def create_connection( infos = _interleave_addrinfos(infos, interleave) exceptions = [] + staggered_exceptions = [] if happy_eyeballs_delay is None: # not using happy eyeballs for addrinfo in infos: @@ -1141,7 +1142,7 @@ async def create_connection( except OSError: continue else: # using happy eyeballs - sock = (await staggered.staggered_race( + sock, _, staggered_exceptions = (await staggered.staggered_race( ( # can't use functools.partial as it keeps a reference # to exceptions @@ -1152,10 +1153,15 @@ async def create_connection( ), happy_eyeballs_delay, loop=self, - ))[0] # can't use sock, _, _ as it keeks a reference to exceptions + )) if sock is None: exceptions = [exc for sub in exceptions for exc in sub] + for exc in staggered_exceptions: + if not (isinstance(exc, CancelledError) or exc in exceptions): + exceptions.append(exc) + del exc + try: if all_errors: raise ExceptionGroup("create_connection failed", exceptions) @@ -1172,6 +1178,7 @@ async def create_connection( ', '.join(str(exc) for exc in exceptions))) finally: exceptions = None + staggered_exceptions = None else: if sock is None: diff --git a/Misc/NEWS.d/next/Library/2025-06-24-06-18-49.gh-issue-135836.7-KHAd.rst b/Misc/NEWS.d/next/Library/2025-06-24-06-18-49.gh-issue-135836.7-KHAd.rst new file mode 100644 index 00000000000000..1ce37aa42a359a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-24-06-18-49.gh-issue-135836.7-KHAd.rst @@ -0,0 +1 @@ +Fix :exc:`IndexError` in :meth:`asyncio.loop.create_connection` that could occur when the Happy Eyeballs algorithm resulted in an empty exceptions list during connection attempts, by capturing any exceptions raised by ``staggered_race``