@@ -18,7 +18,7 @@ def _get_dump(cls):
1818 cls ._abc_negative_cache , cls ._abc_negative_cache_version )
1919
2020
21- def dash_R (the_module , test , indirect_test , huntrleaks ):
21+ def dash_R (ns , the_module , test_name , test_func ):
2222 """Run a test multiple times, looking for reference leaks.
2323
2424 Returns:
@@ -32,6 +32,10 @@ def dash_R(the_module, test, indirect_test, huntrleaks):
3232 raise Exception ("Tracking reference leaks requires a debug build "
3333 "of Python" )
3434
35+ # Avoid false positives due to various caches
36+ # filling slowly with random data:
37+ warm_caches ()
38+
3539 # Save current values for dash_R_cleanup() to restore.
3640 fs = warnings .filters [:]
3741 ps = copyreg .dispatch_table .copy ()
@@ -57,31 +61,50 @@ def dash_R(the_module, test, indirect_test, huntrleaks):
5761 def get_pooled_int (value ):
5862 return int_pool .setdefault (value , value )
5963
60- nwarmup , ntracked , fname = huntrleaks
64+ nwarmup , ntracked , fname = ns . huntrleaks
6165 fname = os .path .join (support .SAVEDCWD , fname )
6266 repcount = nwarmup + ntracked
67+
68+ # Pre-allocate to ensure that the loop doesn't allocate anything new
69+ rep_range = list (range (repcount ))
6370 rc_deltas = [0 ] * repcount
6471 alloc_deltas = [0 ] * repcount
6572 fd_deltas = [0 ] * repcount
73+ getallocatedblocks = sys .getallocatedblocks
74+ gettotalrefcount = sys .gettotalrefcount
75+ fd_count = support .fd_count
6676
67- print ("beginning" , repcount , "repetitions" , file = sys .stderr )
68- print (("1234567890" * (repcount // 10 + 1 ))[:repcount ], file = sys .stderr ,
69- flush = True )
7077 # initialize variables to make pyflakes quiet
7178 rc_before = alloc_before = fd_before = 0
72- for i in range (repcount ):
73- indirect_test ()
74- alloc_after , rc_after , fd_after = dash_R_cleanup (fs , ps , pic , zdc ,
75- abcs )
76- print ('.' , end = '' , file = sys .stderr , flush = True )
77- if i >= nwarmup :
78- rc_deltas [i ] = get_pooled_int (rc_after - rc_before )
79- alloc_deltas [i ] = get_pooled_int (alloc_after - alloc_before )
80- fd_deltas [i ] = get_pooled_int (fd_after - fd_before )
79+
80+ if not ns .quiet :
81+ print ("beginning" , repcount , "repetitions" , file = sys .stderr )
82+ print (("1234567890" * (repcount // 10 + 1 ))[:repcount ], file = sys .stderr ,
83+ flush = True )
84+
85+ for i in rep_range :
86+ test_func ()
87+ dash_R_cleanup (fs , ps , pic , zdc , abcs )
88+
89+ # Collect cyclic trash and read memory statistics immediately after.
90+ support .gc_collect ()
91+ alloc_after = getallocatedblocks ()
92+ rc_after = gettotalrefcount ()
93+ fd_after = fd_count ()
94+
95+ if not ns .quiet :
96+ print ('.' , end = '' , file = sys .stderr , flush = True )
97+
98+ rc_deltas [i ] = get_pooled_int (rc_after - rc_before )
99+ alloc_deltas [i ] = get_pooled_int (alloc_after - alloc_before )
100+ fd_deltas [i ] = get_pooled_int (fd_after - fd_before )
101+
81102 alloc_before = alloc_after
82103 rc_before = rc_after
83104 fd_before = fd_after
84- print (file = sys .stderr )
105+
106+ if not ns .quiet :
107+ print (file = sys .stderr )
85108
86109 # These checkers return False on success, True on failure
87110 def check_rc_deltas (deltas ):
@@ -112,7 +135,7 @@ def check_fd_deltas(deltas):
112135 deltas = deltas [nwarmup :]
113136 if checker (deltas ):
114137 msg = '%s leaked %s %s, sum=%s' % (
115- test , deltas , item_name , sum (deltas ))
138+ test_name , deltas , item_name , sum (deltas ))
116139 print (msg , file = sys .stderr , flush = True )
117140 with open (fname , "a" ) as refrep :
118141 print (msg , file = refrep )
@@ -122,7 +145,7 @@ def check_fd_deltas(deltas):
122145
123146
124147def dash_R_cleanup (fs , ps , pic , zdc , abcs ):
125- import gc , copyreg
148+ import copyreg
126149 import collections .abc
127150
128151 # Restore some original values.
@@ -154,16 +177,8 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs):
154177
155178 clear_caches ()
156179
157- # Collect cyclic trash and read memory statistics immediately after.
158- func1 = sys .getallocatedblocks
159- func2 = sys .gettotalrefcount
160- gc .collect ()
161- return func1 (), func2 (), support .fd_count ()
162-
163180
164181def clear_caches ():
165- import gc
166-
167182 # Clear the warnings registry, so they can be displayed again
168183 for mod in sys .modules .values ():
169184 if hasattr (mod , '__warningregistry__' ):
@@ -256,7 +271,7 @@ def clear_caches():
256271 for f in typing ._cleanups :
257272 f ()
258273
259- gc . collect ()
274+ support . gc_collect ()
260275
261276
262277def warm_caches ():
0 commit comments