@@ -18,7 +18,7 @@ def _get_dump(cls):
18
18
cls ._abc_negative_cache , cls ._abc_negative_cache_version )
19
19
20
20
21
- def dash_R (the_module , test , indirect_test , huntrleaks ):
21
+ def dash_R (ns , the_module , test_name , test_func ):
22
22
"""Run a test multiple times, looking for reference leaks.
23
23
24
24
Returns:
@@ -32,6 +32,10 @@ def dash_R(the_module, test, indirect_test, huntrleaks):
32
32
raise Exception ("Tracking reference leaks requires a debug build "
33
33
"of Python" )
34
34
35
+ # Avoid false positives due to various caches
36
+ # filling slowly with random data:
37
+ warm_caches ()
38
+
35
39
# Save current values for dash_R_cleanup() to restore.
36
40
fs = warnings .filters [:]
37
41
ps = copyreg .dispatch_table .copy ()
@@ -57,31 +61,50 @@ def dash_R(the_module, test, indirect_test, huntrleaks):
57
61
def get_pooled_int (value ):
58
62
return int_pool .setdefault (value , value )
59
63
60
- nwarmup , ntracked , fname = huntrleaks
64
+ nwarmup , ntracked , fname = ns . huntrleaks
61
65
fname = os .path .join (support .SAVEDCWD , fname )
62
66
repcount = nwarmup + ntracked
67
+
68
+ # Pre-allocate to ensure that the loop doesn't allocate anything new
69
+ rep_range = list (range (repcount ))
63
70
rc_deltas = [0 ] * repcount
64
71
alloc_deltas = [0 ] * repcount
65
72
fd_deltas = [0 ] * repcount
73
+ getallocatedblocks = sys .getallocatedblocks
74
+ gettotalrefcount = sys .gettotalrefcount
75
+ fd_count = support .fd_count
66
76
67
- print ("beginning" , repcount , "repetitions" , file = sys .stderr )
68
- print (("1234567890" * (repcount // 10 + 1 ))[:repcount ], file = sys .stderr ,
69
- flush = True )
70
77
# initialize variables to make pyflakes quiet
71
78
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
+
81
102
alloc_before = alloc_after
82
103
rc_before = rc_after
83
104
fd_before = fd_after
84
- print (file = sys .stderr )
105
+
106
+ if not ns .quiet :
107
+ print (file = sys .stderr )
85
108
86
109
# These checkers return False on success, True on failure
87
110
def check_rc_deltas (deltas ):
@@ -112,7 +135,7 @@ def check_fd_deltas(deltas):
112
135
deltas = deltas [nwarmup :]
113
136
if checker (deltas ):
114
137
msg = '%s leaked %s %s, sum=%s' % (
115
- test , deltas , item_name , sum (deltas ))
138
+ test_name , deltas , item_name , sum (deltas ))
116
139
print (msg , file = sys .stderr , flush = True )
117
140
with open (fname , "a" ) as refrep :
118
141
print (msg , file = refrep )
@@ -122,7 +145,7 @@ def check_fd_deltas(deltas):
122
145
123
146
124
147
def dash_R_cleanup (fs , ps , pic , zdc , abcs ):
125
- import gc , copyreg
148
+ import copyreg
126
149
import collections .abc
127
150
128
151
# Restore some original values.
@@ -154,16 +177,8 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs):
154
177
155
178
clear_caches ()
156
179
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
-
163
180
164
181
def clear_caches ():
165
- import gc
166
-
167
182
# Clear the warnings registry, so they can be displayed again
168
183
for mod in sys .modules .values ():
169
184
if hasattr (mod , '__warningregistry__' ):
@@ -256,7 +271,7 @@ def clear_caches():
256
271
for f in typing ._cleanups :
257
272
f ()
258
273
259
- gc . collect ()
274
+ support . gc_collect ()
260
275
261
276
262
277
def warm_caches ():
0 commit comments