Method call after garbage collection is finished

I have a class “Foo” where the objects are registered in an object called FooManager. After the scope of a function is left the Foo objects can only be deleted if I know ALL the Foos which are “tagged for deletion”.

class FooManager:
    
    def __init__(self):
        self.deletion_list = []
    
    def delete_tagged_foos(self):
        #Deletion process
        pass

class Foo:

    def __init__(self, FooManager):
        self.FooManager = FooManager

    def __del__(self):
        self.FooManager.deletion_list.append(self)

        if garbage_collection_finished():
            self.FooManager.delete_tagged_foos()


def foo_processing(manager):
    foo1 = Foo(manager)
    foo2 = Foo(manager)
    foo3 = Foo(manager)
    
    # Tag foo2 and foo3 for deletion (but not foo1)
    # and perform deletion process once every foo is tagged
    return foo1


manager = FooManager()

foo1 = foo_processing(manager)

How can I acquire the boolean garbage_collection_finished()?

Answer

How about keeping track of foo instances in the FooManager and using it as a decorator on functions that create temporary foo instances:

import sys

class FooManager:
    
    def __init__(self):
        self.foos = []

    def registerFoo(self,foo):
        foo.FooManager = self
        self.foos.append(foo)
        print("+1")

    def cleanFoos(self,func):
        def callFunc(*args,**kwargs):
            result = func(*args,**kwargs)
            # 3 refs = self.foos, foo in comprehension, getrefcount param
            orphanFoos = [foo for foo in self.foos if sys.getrefcount(foo)<=3]
            # process orphans as needed
            # leave them in self.foos if they are not to be deleted
            self.foos  = [foo for foo in self.foos if foo not in orphanFoos]
            # ...
            print("foo count:",len(self.foos))
            return result 
        return callFunc
        
class Foo:

    def __init__(self, FooManager):
        FooManager.registerFoo(self)

    def __del__(self): print("deleted")

usage:

manager = FooManager()

@manager.cleanFoos
def foo_processing(manager):
    foo1 = Foo(manager)
    foo2 = Foo(manager)
    foo3 = Foo(manager)
    
    # Tag foo2 and foo3 for deletion (but not foo1)
    # and perform deletion process once every foo is tagged
    return foo1

foo1 = foo_processing(manager)

output:

+1
+1
+1
foo count: 1
deleted
deleted