Thanks Alex and Scott for your lead. It would've taken me forever trying to figure it out by myself :)
I am affraid I didn't specify initially one thing and that led to a confusion: there is no need to pick an instance from the weakref dictionary, just return None if there are already 5 instances. But on the other hand if a hardref to an object was deleted, it's place can be taken by another one. Here's what i mean (and where the problem is): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #build a list of 5 elements instList=[] for i in range(7): ainst=A() if ainst: instList.append(ainst) for i in range(5): instList.remove(instList[0]) #here the hardref is deleted ainst=A() while not ainst: #make shure that ainst is not NoneType gc.collect() time.sleep(1) #wait 1 sec for gc() to clean the memory ainst=A() #try again instList.append(ainst) #new object added ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ the priblem is that ~3 out of 10 times the test part run into infinite loop because of unsatisfied condition (while not ainst:) - memory cannot be freed therefore new instance of A isn't permitted. #!/usr/bin/env python import weakref,random import types,gc import time class Limited5(object): __weakrefdict=weakref.WeakValueDictionary() def __new__(cls,*args,**kwargs): if len(cls.__weakrefdict)<5: instance=super(Limited5,cls).__new__(cls,*args,**kwargs) cls.__weakrefdict[id(instance)]=instance return instance # return random.choice(cls.__weakrefdict.values()) return None #no need to pick an instance class A(Limited5): counter=0 def __init__(self): self.instCounter=self.counter A.counter+=1 def getId(self): return id(self) if __name__=="__main__": instList=[] # populate the initial list of objects #make shure that there are only 5 elements for item in range(7): ainst=A() if hasattr(ainst,"getId"): print ainst.getId()," -- ",ainst.instCounter instList.append(ainst) print "---------------------------------------------" #delete and recreate an arbitrary element in the instList for i in range(len(instList)): instList.remove(instList[random.choice(range(len(instList)))]) ainst=A() while not ainst: #here is an unstable part ainst=A() #sometimes the loop becomes infinite print gc.collect() #decpite the explicit call for gc() to start time.sleep(1) print "*", instList.append(ainst) for item in instList: print item.getId()," -- ",item.instCounter #print "-------> ",item print "++++++++++++++++++++++++++++" -- http://mail.python.org/mailman/listinfo/python-list