import typing class FinalException(Exception): pass class Final: def __init_subclass__(cls, **kwargs) -> None: for base in cls.__bases__: if base is not Final and issubclass(base, Final): raise FinalException(base) super().__init_subclass__(**kwargs) def check_final(cls): try: class Subclass(cls): pass except FinalException: pass else: raise Exception('Should raise') class NonGenericFinal(Final): pass check_final(NonGenericFinal) T = typing.TypeVar('T') class GenericFinal(typing.Generic[T], Final): pass check_final(GenericFinal)