Skip to content

Subclasses are GC'ed even though it changes __subclasses__() results #130072

@rentruewang

Description

@rentruewang

Bug report

Bug description:

Let's say I have an abstract class / protocol.

However, some of them are automatically generated in anonymous scopes as syntax sugar (in below's example, function is easier to write than ExtendBaseClass).

I would have to access it through __subclasses__().

Since __subclasses__ behavior changes just by calling gc.collect(), I believe this to be a bug.

See code below:

class SomeBaseClass:
    def compute(self) -> int:
        return 1


def adapt_function(f):
    class ExtendBaseClass(SomeBaseClass):
        def compute(self):
            return f()

    return f


@adapt_function
def function():
    return 2


def find_all_subclass(cls: type, result: set):
    result.add(cls)

    for subcls in cls.__subclasses__():
        find_all_subclass(subcls, result)


def main():
    result = set()
    find_all_subclass(SomeBaseClass, result)
    print(result)


if __name__ == "__main__":
    print("Before GC")
    main()
    import gc

    gc.collect()
    print("After GC")
    main()

Output:

(venv) ➜  ~ python main.py
Before GC
{<class '__main__.adapt_function.<locals>.ExtendBaseClass'>, <class '__main__.SomeBaseClass'>}
After GC
{<class '__main__.SomeBaseClass'>}

CPython versions tested on:

3.11

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)pendingThe issue will be closed if no feedback is provided

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions