from collections import defaultdict

class ClassTree:
    def __init__(self):
        self.base_of = {}
        self.ch = defaultdict(set)
        
    def add(self, cls):
        if cls is None:
            return
        
        base = cls.__base__
        
        self.add(base)
        
        self.base_of[cls] = base
        self.ch[base].add(cls)
        
    @staticmethod
    def get_base_chain(cls):  # 废弃
        while cls is not None:
            yield cls
            cls = cls.__base__
            
    def dfs(self, cls):
        yield cls
        for c in self.ch.get(cls, []):
            yield from self.dfs(c)

class ObjectPool:
    def __init__(self):
        self.ct = ClassTree()
        self.obj_pool = defaultdict(set)
        
    def add(self, obj):
        self.ct.add(type(obj))
        self.obj_pool[type(obj)].add(obj)
    
    def remove(self, obj):
        self.obj_pool[type(obj)].remove(obj)
    
    def getall(self, cls):
        for i in self.ct.dfs(cls):
            yield from self.obj_pool[i]
      

class BaseTask:
    pass


class TaskQueue:
    def __init__(self):
        self.taskpool = ObjectPool()
        self.queue = []
        
    def __len__(self):
        return len(self.queue)  
    
    def push(self, task):
        self.queue.append(task)
        self.taskpool.add(task)
    
    def front(self):
        return self.queue[0]
    
    def pop(self):
        task = self.queue.pop(0)
        self.taskpool.remove(task)
        return task
    
    def getall(self, tasktype):
        return self.taskpool.getall(tasktype)
    
    def pushes(self, *args):
        for i in args:
            self.push(i)

if __name__ == '__main__':
    tq = TaskQueue()
    tq.pushes(1, None, 1.2, True, (), int, 1+2j)
    print(tq.pop())
    print(set(tq.getall(int)))
    print(set(tq.getall(None)))