import collections.abc
import concurrent.futures
import errno
-import functools
import heapq
import itertools
import os
except OSError:
continue
else: # using happy eyeballs
- sock, _, _ = await staggered.staggered_race(
- (functools.partial(self._connect_sock,
- exceptions, addrinfo, laddr_infos)
- for addrinfo in infos),
- happy_eyeballs_delay, loop=self)
+ sock = (await staggered.staggered_race(
+ (
+ # can't use functools.partial as it keeps a reference
+ # to exceptions
+ lambda addrinfo=addrinfo: self._connect_sock(
+ exceptions, addrinfo, laddr_infos
+ )
+ for addrinfo in infos
+ ),
+ 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]
messages = self._basetest_unhandled_exceptions(handle_echo)
self.assertEqual(messages, [])
+ def test_open_connection_happy_eyeball_refcycles(self):
+ port = socket_helper.find_unused_port()
+ async def main():
+ exc = None
+ try:
+ await asyncio.open_connection(
+ host="localhost",
+ port=port,
+ happy_eyeballs_delay=0.25,
+ )
+ except* OSError as excs:
+ # can't use assertRaises because that clears frames
+ exc = excs.exceptions[0]
+ self.assertIsNotNone(exc)
+ self.assertListEqual(gc.get_referrers(exc), [])
+
+ asyncio.run(main())
+
if __name__ == '__main__':
unittest.main()