Which classes cannot be subclassed?
class, inheritance, language-design, python, python-3.x
Solution
There seems to be two reasons for a class to be "final" in Python.
1. Violation of Class Invariant
Classes that follow Singleton pattern have an invariant that there's a limited (pre-determined) number of instances. Any violation of this invariant in a subclass will be inconsistent with the class' intent, and would not work correctly. Examples:
- `bool`: `True`, `False`; see Guido's comments
- `NoneType`: `None`
- `NotImplementedType`: `NotImplemented`
- `ellipsis`: `Ellipsis`
There may be cases other than the Singleton pattern in this category but I'm not aware of any.
2. No Persuasive Use Case
A class implemented in C requires additional work to allow subclassing (at least in CPython). Doing such work without a convincing use case is not very attractive, so volunteers are less likely to come forward. Examples:
- `function`; see Tim Peters' post
Note 1:
I originally thought there were valid use cases, but simply insufficient interest, in subclassing of `function` and `operator.itemgetter`. Thanks to @agf for pointing out that the use cases offered here and here are not convincing (see @agf comments to the question).
Note 2:
My concern is that another Python implementation might accidentally allow subclassing a class that's final in CPython. This may result in non-portable code (a use case may be weak, but someone might still write code that subclasses `function` if their Python supports it). This can be resolved by marking in Python documentation all built-in and standard library classes that cannot be subclassed, and requiring that all implementations follow CPython behavior in that respect.
Note 3:
The message produced by CPython in all the above cases is:
TypeError: type 'bool' is not an acceptable base type
It is quite cryptic, as numerous questions on this subject show. I'll submit a suggestion to add a paragraph to the documentation that explains final classes, and maybe even change the error message to:
TypeError: type 'bool' is final (non-extensible)
Problem
Is there any rule about which built-in and standard library classes are not subclassable ("final")? As of Python 3.3, here are a few examples: - `bool` - `function` - `operator.itemgetter` - `slice` I found a question which deals with the implementation of "final" classes, both in C and pure Python. I would like to understand what reasons may explain why a class is chosen to be "final" in the first place.