Skip to content

ALL-OVER0009 · final_class_subclassed

Detect a class that inherits from a class its author sealed against inheritance.

This is a deterministic rule for all languages. Read its implementation.

Report a direct base decorated final. Sealing a class is the strongest statement an author can make about it, which is that the class reasons about its own state and was never designed to have a stranger reach into the middle of it. Subclassing one anyway means every invariant it documented is now a guess, and the author who sealed it is free to change anything at all in the next release because nobody was supposed to be standing there.

The marker lives on the base, usually in another file, so the defect only exists as a relation between two classes and a resolved inheritance chain is the only thing that holds it.

Each finding names the subclass, the sealed base, and the decorator that sealed it. The value says whether this link crosses a seal.

Only a direct base is judged, because a class further up was sealed against whoever inherited it first and that is where the report belongs. A project sealing a class through a decorator of its own making is not read, since the graph records the decorator a class wrote and not what that decorator returns.

A type checker also reports this, and it is worth reporting twice, because the marker exists to be enforced and a project that runs no type checker still deserves the answer.

@final
class Money:
def __init__(self, cents):
self.cents = cents
class Discount(Money):
def apply(self, rate):
self.cents = int(self.cents * rate)
class Discount:
def __init__(self, amount):
self.amount = amount
  • Generalizes Pylint W0240 subclassed-final-class. Open reference
  • Cites “PEP 591, Adding a Final Qualifier to Typing”. Open reference
  • Cites “Effective Java”, design and document for inheritance or else prohibit it