@@ -1219,23 +1219,35 @@ def test_shutdown_close_idle_keepalive(
12191219 sock = unused_port_socket
12201220 port = sock .getsockname ()[1 ]
12211221 t = None
1222+ sess_holder : list [ClientSession ] = []
12221223
12231224 async def test () -> None :
12241225 await asyncio .sleep (1 )
1225- async with ClientSession () as sess :
1226+ sess = ClientSession ()
1227+ sess_holder .append (sess )
1228+ async with sess :
12261229 async with sess .get (f"http://127.0.0.1:{ port } /stop" ):
12271230 pass
1228-
12291231 # Hold on to keep-alive connection.
12301232 await asyncio .sleep (5 )
12311233
12321234 async def run_test (app : web .Application ) -> AsyncIterator [None ]:
12331235 nonlocal t
12341236 t = asyncio .create_task (test ())
12351237 yield
1236- t .cancel ()
1237- with contextlib .suppress (asyncio .CancelledError ):
1238- await t
1238+ try :
1239+ t .cancel ()
1240+ with contextlib .suppress (asyncio .CancelledError ):
1241+ await t
1242+ finally :
1243+ if sys .platform == "win32" :
1244+ # On Windows, explicitly close the session and yield to the
1245+ # event loop to mitigate resource warnings related to unclosed
1246+ # sockets, which are more common due to ProactorEventLoop
1247+ # timing issues.
1248+ for sess in sess_holder :
1249+ await sess .close ()
1250+ await asyncio .sleep (0.1 )
12391251
12401252 app = web .Application ()
12411253 app .cleanup_ctx .append (run_test )
@@ -1268,9 +1280,13 @@ async def close_websockets(app: web.Application) -> None:
12681280 for ws in app [WS ]:
12691281 await ws .close (code = WSCloseCode .GOING_AWAY )
12701282
1283+ sess_holder : list [ClientSession ] = []
1284+
12711285 async def test () -> None :
12721286 await asyncio .sleep (1 )
1273- async with ClientSession () as sess :
1287+ sess = ClientSession ()
1288+ sess_holder .append (sess )
1289+ async with sess :
12741290 async with sess .ws_connect (f"http://127.0.0.1:{ port } /ws" ) as ws :
12751291 async with sess .get (f"http://127.0.0.1:{ port } /stop" ):
12761292 pass
@@ -1285,9 +1301,18 @@ async def run_test(app: web.Application) -> AsyncIterator[None]:
12851301 t = asyncio .create_task (test ())
12861302 yield
12871303 await asyncio .sleep (0 ) # In case test() hasn't resumed yet.
1288- t .cancel ()
1289- with contextlib .suppress (asyncio .CancelledError ):
1290- await t
1304+ try :
1305+ try :
1306+ await asyncio .wait_for (t , timeout = 3.0 )
1307+ except asyncio .TimeoutError :
1308+ t .cancel ()
1309+ with contextlib .suppress (asyncio .CancelledError ):
1310+ await t
1311+ finally :
1312+ if sys .platform == "win32" :
1313+ for sess in sess_holder :
1314+ await sess .close ()
1315+ await asyncio .sleep (0.1 )
12911316
12921317 app = web .Application ()
12931318 app [WS ] = set ()
0 commit comments