import gc import sys # Unused imports, but removing them "hides" the bug import logging import socket import pickle # --- ############# PySet_MINSIZE = 8 SET_MASK = PySet_MINSIZE - 1 FIXED_HASH = 1 if not FIXED_HASH: hash_values = [None] * 100 else: hash_values = [3, 2, 5, 6, 5, 1, 0, 3, 4, 2, 0, 1, 3, 2, 3, 4, 7, 7, 7, 2, 0, 1, 4, 6, 0, 3, 3, 1, 3, 2, 0, 7, 7, 7, 2] hash_i = 0 class Thread2: def __init__(self): global hash_i if FIXED_HASH: self.hashvalue = hash_values[hash_i] else: k = hash(self) & SET_MASK hash_values[hash_i] = k print(hash_values[:hash_i+1]) hash_i += 1 if FIXED_HASH: def __hash__(self): return self.hashvalue def test_current_frames(): item = Thread2() dangling.add(item) dangling.discard(item) item = None dangling = set() main_thread = Thread2() dangling.add(main_thread) ############### def dash_R(): nwarmup, ntracked = (4, 30) repcount = nwarmup + ntracked alloc_deltas = [0] * ntracked # prealloc all integers for sys.getallocatedblocks() result integers = list(range(50_000)) alloc_before = 0 for i in range(nwarmup): test_current_frames() alloc_before = sys.getallocatedblocks() for i in range(ntracked): test_current_frames() alloc_after = sys.getallocatedblocks() alloc_deltas[i] = alloc_after - alloc_before alloc_before = alloc_after i = None if any(delta >= 1 for delta in alloc_deltas): msg = 'test_leak leaked %s %s, sum=%s' % ( alloc_deltas, 'memory blocks', sum(alloc_deltas)) print(msg, file=sys.stderr, flush=True) failed = True else: print("no leak") failed = False return failed def warm_caches(): # char cache s = bytes(range(256)) for i in range(256): s[i:i+1] # unicode cache [chr(i) for i in range(256)] # int cache list(range(-5, 257)) if __name__ == "__main__": warm_caches() dash_R()