File tree Expand file tree Collapse file tree 3 files changed +24
-48
lines changed Expand file tree Collapse file tree 3 files changed +24
-48
lines changed Original file line number Diff line number Diff line change @@ -263,28 +263,6 @@ def __eager_start(self):
263
263
else :
264
264
_register_task (self )
265
265
266
- def __step (self , exc = None ):
267
- if self .done ():
268
- raise exceptions .InvalidStateError (
269
- f'__step(): already done: { self !r} , { exc !r} ' )
270
- if self ._must_cancel :
271
- if not isinstance (exc , exceptions .CancelledError ):
272
- exc = self ._make_cancelled_error ()
273
- self ._must_cancel = False
274
- self ._fut_waiter = None
275
-
276
- _enter_task (self ._loop , self )
277
- try :
278
- self .__step_run_and_handle_result (exc )
279
- finally :
280
- if self .done ():
281
- # Clear the callback chain and residual references
282
- self ._callbacks .clear () # Clean up the callback list
283
- self ._exception = None # Release the reference to the exception object
284
- if hasattr (self , '_context' ):
285
- self ._context = None # Python 3.11+ Clean up context variables
286
- _leave_task (self ._loop , self )
287
- self = None # Needed to break cycles when an exception occurs.
288
266
289
267
def __step_run_and_handle_result (self , exc ):
290
268
coro = self ._coro
Original file line number Diff line number Diff line change @@ -1117,30 +1117,4 @@ def loop_factory():
1117
1117
if __name__ == "__main__" :
1118
1118
unittest .main ()
1119
1119
1120
- """
1121
- This test case verifies that cancelled asyncio tasks are properly garbage collected
1122
- and do not cause memory leaks. It creates a large number of tasks, cancels them,
1123
- and checks for remaining Task objects after garbage collection.
1124
- """
1125
1120
1126
- import unittest
1127
- import asyncio
1128
- import gc
1129
-
1130
- class TestTaskMemoryLeak (unittest .TestCase ):
1131
- async def test_cancelled_task_cleanup (self ):
1132
- async def dummy ():
1133
- await asyncio .sleep (0.1 )
1134
-
1135
- # Create and cancel 10,000 tasks
1136
- tasks = [asyncio .create_task (dummy ()) for _ in range (10_000 )]
1137
- for t in tasks :
1138
- t .cancel ()
1139
-
1140
- # Wait for all tasks to complete cleanup
1141
- await asyncio .gather (* tasks , return_exceptions = True )
1142
- del tasks
1143
-
1144
- # Trigger garbage collection and verify memory release
1145
- gc .collect ()
1146
- self .assertEqual (len ([obj for obj in gc .get_objects () if isinstance (obj , asyncio .Task )]), 0 )
Original file line number Diff line number Diff line change @@ -3615,4 +3615,28 @@ def tearDown(self):
3615
3615
if __name__ == '__main__' :
3616
3616
unittest .main ()
3617
3617
3618
+ """
3619
+ This test case verifies that cancelled asyncio tasks are properly garbage collected
3620
+ and do not cause memory leaks. It creates a large number of tasks, cancels them,
3621
+ and checks for remaining Task objects after garbage collection.
3622
+ """
3618
3623
3624
+
3625
+
3626
+ class TestTaskMemoryLeak (unittest .TestCase ):
3627
+ async def test_cancelled_task_cleanup (self ):
3628
+ async def dummy ():
3629
+ await asyncio .sleep (0.1 )
3630
+
3631
+ # Create and cancel 10,000 tasks
3632
+ tasks = [asyncio .create_task (dummy ()) for _ in range (10_000 )]
3633
+ for t in tasks :
3634
+ t .cancel ()
3635
+
3636
+ # Wait for all tasks to complete cleanup
3637
+ await asyncio .gather (* tasks , return_exceptions = True )
3638
+ del tasks
3639
+
3640
+ # Trigger garbage collection and verify memory release
3641
+ gc .collect ()
3642
+ self .assertEqual (len ([obj for obj in gc .get_objects () if isinstance (obj , asyncio .Task )]), 0 )
You can’t perform that action at this time.
0 commit comments