@@ -356,47 +356,25 @@ def __del__(self):
356356 gc .disable ()
357357 gc .set_threshold (* thresholds )
358358
359- # The following two tests are fragile:
360- # They precisely count the number of allocations,
361- # which is highly implementation-dependent.
362- # For example, disposed tuples are not freed, but reused.
363- # To minimize variations, though, we first store the get_count() results
364- # and check them at the end.
359+ # The following test is implementation-dependent because it
360+ # counts the number of allocations.
365361 @refcount_test
366362 def test_get_count (self ):
367363 gc .collect ()
368364 a , b , c = gc .get_count ()
369- x = []
365+ # Note: get_count() isn't precise. To enable faster allocations,
366+ # it is only updated when mimalloc "pages" become full or are no
367+ # longer full.
368+ tmp = []
369+ for _ in range (2048 ):
370+ tmp .append (['' ])
370371 d , e , f = gc .get_count ()
371372 self .assertEqual ((b , c ), (0 , 0 ))
372373 self .assertEqual ((e , f ), (0 , 0 ))
373- # This is less fragile than asserting that a equals 0.
374- self .assertLess (a , 5 )
375- # Between the two calls to get_count(), at least one object was
376- # created (the list).
374+ # Between the two calls to get_count(), enough objects were
375+ # created to increase the count.
377376 self .assertGreater (d , a )
378377
379- @refcount_test
380- def test_collect_generations (self ):
381- gc .collect ()
382- # This object will "trickle" into generation N + 1 after
383- # each call to collect(N)
384- x = []
385- gc .collect (0 )
386- # x is now in gen 1
387- a , b , c = gc .get_count ()
388- gc .collect (1 )
389- # x is now in gen 2
390- d , e , f = gc .get_count ()
391- gc .collect (2 )
392- # x is now in gen 3
393- g , h , i = gc .get_count ()
394- # We don't check a, d, g since their exact values depends on
395- # internal implementation details of the interpreter.
396- self .assertEqual ((b , c ), (1 , 0 ))
397- self .assertEqual ((e , f ), (0 , 1 ))
398- self .assertEqual ((h , i ), (0 , 0 ))
399-
400378 def test_trashcan (self ):
401379 class Ouch :
402380 n = 0
@@ -784,7 +762,7 @@ def __del__(self):
784762
785763 def test_get_stats (self ):
786764 stats = gc .get_stats ()
787- self .assertEqual (len (stats ), 3 )
765+ self .assertEqual (len (stats ), 1 )
788766 for st in stats :
789767 self .assertIsInstance (st , dict )
790768 self .assertEqual (set (st ),
@@ -797,20 +775,14 @@ def test_get_stats(self):
797775 self .addCleanup (gc .enable )
798776 gc .disable ()
799777 old = gc .get_stats ()
800- gc .collect (0 )
801- new = gc .get_stats ()
802- self .assertEqual (new [0 ]["collections" ], old [0 ]["collections" ] + 1 )
803- self .assertEqual (new [1 ]["collections" ], old [1 ]["collections" ])
804- self .assertEqual (new [2 ]["collections" ], old [2 ]["collections" ])
805- gc .collect (2 )
778+ gc .collect ()
806779 new = gc .get_stats ()
807780 self .assertEqual (new [0 ]["collections" ], old [0 ]["collections" ] + 1 )
808- self .assertEqual (new [1 ]["collections" ], old [1 ]["collections" ])
809- self .assertEqual (new [2 ]["collections" ], old [2 ]["collections" ] + 1 )
810781
811782 def test_freeze (self ):
783+ # freeze no longer does anything, so count is always zero :(
812784 gc .freeze ()
813- self .assertGreater (gc .get_freeze_count (), 0 )
785+ self .assertEqual (gc .get_freeze_count (), 0 )
814786 gc .unfreeze ()
815787 self .assertEqual (gc .get_freeze_count (), 0 )
816788
@@ -819,52 +791,17 @@ def test_get_objects(self):
819791 l = []
820792 l .append (l )
821793 self .assertTrue (
822- any (l is element for element in gc .get_objects (generation = 0 ))
823- )
824- self .assertFalse (
825- any (l is element for element in gc .get_objects (generation = 1 ))
826- )
827- self .assertFalse (
828- any (l is element for element in gc .get_objects (generation = 2 ))
829- )
830- gc .collect (generation = 0 )
831- self .assertFalse (
832- any (l is element for element in gc .get_objects (generation = 0 ))
833- )
834- self .assertTrue (
835- any (l is element for element in gc .get_objects (generation = 1 ))
836- )
837- self .assertFalse (
838- any (l is element for element in gc .get_objects (generation = 2 ))
839- )
840- gc .collect (generation = 1 )
841- self .assertFalse (
842- any (l is element for element in gc .get_objects (generation = 0 ))
843- )
844- self .assertFalse (
845- any (l is element for element in gc .get_objects (generation = 1 ))
846- )
847- self .assertTrue (
848- any (l is element for element in gc .get_objects (generation = 2 ))
849- )
850- gc .collect (generation = 2 )
851- self .assertFalse (
852- any (l is element for element in gc .get_objects (generation = 0 ))
853- )
854- self .assertFalse (
855- any (l is element for element in gc .get_objects (generation = 1 ))
794+ any (l is element for element in gc .get_objects ())
856795 )
796+ gc .collect ()
857797 self .assertTrue (
858- any (l is element for element in gc .get_objects (generation = 2 ))
798+ any (l is element for element in gc .get_objects ())
859799 )
860800 del l
861801 gc .collect ()
862802
863803 def test_get_objects_arguments (self ):
864- gc .collect ()
865- self .assertEqual (len (gc .get_objects ()),
866- len (gc .get_objects (generation = None )))
867-
804+ self .assertGreater (len (gc .get_objects ()), 0 )
868805 self .assertRaises (ValueError , gc .get_objects , 1000 )
869806 self .assertRaises (ValueError , gc .get_objects , - 1000 )
870807 self .assertRaises (TypeError , gc .get_objects , "1" )
@@ -1147,10 +1084,10 @@ def test_collect(self):
11471084
11481085 def test_collect_generation (self ):
11491086 self .preclean ()
1150- gc .collect (2 )
1087+ gc .collect (0 )
11511088 for v in self .visit :
11521089 info = v [2 ]
1153- self .assertEqual (info ["generation" ], 2 )
1090+ self .assertEqual (info ["generation" ], 0 )
11541091
11551092 @cpython_only
11561093 def test_collect_garbage (self ):
@@ -1304,15 +1241,9 @@ def callback(ignored):
13041241
13051242 # We want to let gc happen "naturally", to preserve the distinction
13061243 # between generations.
1307- junk = []
1308- i = 0
1309- detector = GC_Detector ()
1310- while not detector .gc_happened :
1311- i += 1
1312- if i > 10000 :
1313- self .fail ("gc didn't happen after 10000 iterations" )
1314- self .assertEqual (len (ouch ), 0 )
1315- junk .append ([]) # this will eventually trigger gc
1244+ # TODO(sgross): revisit this. no guaranteed "natural" collection, so trigger
1245+ # a collection manually.
1246+ gc .collect ()
13161247
13171248 self .assertEqual (len (ouch ), 1 ) # else the callback wasn't invoked
13181249 for x in ouch :
@@ -1371,15 +1302,9 @@ def __del__(self):
13711302
13721303 # We want to let gc happen "naturally", to preserve the distinction
13731304 # between generations.
1374- detector = GC_Detector ()
1375- junk = []
1376- i = 0
1377- while not detector .gc_happened :
1378- i += 1
1379- if i > 10000 :
1380- self .fail ("gc didn't happen after 10000 iterations" )
1381- self .assertEqual (len (ouch ), 0 )
1382- junk .append ([]) # this will eventually trigger gc
1305+ # TODO(sgross): revisit this. no guaranteed "natural" collection, so trigger
1306+ # a collection manually.
1307+ gc .collect ()
13831308
13841309 self .assertEqual (len (ouch ), 1 ) # else __del__ wasn't invoked
13851310 for x in ouch :
0 commit comments