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.

Original source

Related problems