Skip to content

[mypyc] Report an error if an acyclic class inherits from non-acyclic#21227

Merged
p-sawicki merged 3 commits intopython:masterfrom
p-sawicki:acyclic-inherits-non-acyclic-error
Apr 15, 2026
Merged

[mypyc] Report an error if an acyclic class inherits from non-acyclic#21227
p-sawicki merged 3 commits intopython:masterfrom
p-sawicki:acyclic-inherits-non-acyclic-error

Conversation

@p-sawicki
Copy link
Copy Markdown
Collaborator

Classes marked with @mypyc_attr(acyclic=True) are generated without the Py_TPFLAGS_HAVE_GC flag which opts them out of the cyclic GC. However, when they inherit from a class that does have this flag, cpython opts them back into the cyclic GC in inherit_special https://github.com/python/cpython/blob/main/Objects/typeobject.c#L8614.

The destructor generated by mypyc for acyclic classes does not untrack the instances before deallocating them which makes cpython issue a warning in debug builds https://github.com/python/cpython/blob/main/Python/gc.c#L2538. I wasn't able to confirm whether this can cause memory leaks but it's probably best to disallow this case.

This also affects generic classes that use the new type parameter syntax class C[T]. They implicitly inherit from typing.Generic which opts into GC https://github.com/python/cpython/blob/main/Objects/typevarobject.c#L2350.

pass

@mypyc_attr(acyclic=True)
class BadGeneric(Generic[T]): # E: "acyclic" can't be used in a class that inherits from non-acyclic type "typing.Generic"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about testing traits and non-native classes as bases (fine to do this in a follow-up PR)?

@p-sawicki p-sawicki merged commit d0f5550 into python:master Apr 15, 2026
17 checks passed
@p-sawicki p-sawicki deleted the acyclic-inherits-non-acyclic-error branch April 15, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants