| .. _final_attrs: | |
| Final names, methods and classes | |
| ================================ | |
| This section introduces these related features: | |
| 1. *Final names* are variables or attributes that should not be reassigned after | |
| initialization. They are useful for declaring constants. | |
| 2. *Final methods* should not be overridden in a subclass. | |
| 3. *Final classes* should not be subclassed. | |
| All of these are only enforced by mypy, and only in annotated code. | |
| There is no runtime enforcement by the Python runtime. | |
| .. note:: | |
| The examples in this page import ``Final`` and ``final`` from the | |
| ``typing`` module. These types were added to ``typing`` in Python 3.8, | |
| but are also available for use in Python 3.4 - 3.7 via the | |
| ``typing_extensions`` package. | |
| Final names | |
| ----------- | |
| You can use the ``typing.Final`` qualifier to indicate that | |
| a name or attribute should not be reassigned, redefined, or | |
| overridden. This is often useful for module and class-level | |
| constants to prevent unintended modification. Mypy will prevent | |
| further assignments to final names in type-checked code: | |
| .. code-block:: python | |
| from typing import Final | |
| RATE: Final = 3_000 | |
| class Base: | |
| DEFAULT_ID: Final = 0 | |
| RATE = 300 # Error: can't assign to final attribute | |
| Base.DEFAULT_ID = 1 # Error: can't override a final attribute | |
| Another use case for final attributes is to protect certain attributes | |
| from being overridden in a subclass: | |
| .. code-block:: python | |
| from typing import Final | |
| class Window: | |
| BORDER_WIDTH: Final = 2.5 | |
| ... | |
| class ListView(Window): | |
| BORDER_WIDTH = 3 # Error: can't override a final attribute | |
| You can use :py:class:`@property <property>` to make an attribute read-only, but unlike ``Final``, | |
| it doesn't work with module attributes, and it doesn't prevent overriding in | |
| subclasses. | |
| Syntax variants | |
| *************** | |
| You can use ``Final`` in one of these forms: | |
| * You can provide an explicit type using the syntax ``Final[<type>]``. Example: | |
| .. code-block:: python | |
| ID: Final[int] = 1 | |
| Here, mypy will infer type ``int`` for ``ID``. | |
| * You can omit the type: | |
| .. code-block:: python | |
| ID: Final = 1 | |
| Here, mypy will infer type ``Literal[1]`` for ``ID``. Note that unlike for | |
| generic classes, this is *not* the same as ``Final[Any]``. | |
| * In class bodies and stub files, you can omit the right-hand side and just write | |
| ``ID: Final[int]``. | |
| * Finally, you can write ``self.id: Final = 1`` (also optionally with | |
| a type in square brackets). This is allowed *only* in | |
| :py:meth:`__init__ <object.__init__>` methods so the final instance attribute is | |
| assigned only once when an instance is created. | |
| Details of using ``Final`` | |
| ************************** | |
| These are the two main rules for defining a final name: | |
| * There can be *at most one* final declaration per module or class for | |
| a given attribute. There can't be separate class-level and instance-level | |
| constants with the same name. | |
| * There must be *exactly one* assignment to a final name. | |
| A final attribute declared in a class body without an initializer must | |
| be initialized in the :py:meth:`__init__ <object.__init__>` method (you can skip the | |
| initializer in stub files): | |
| .. code-block:: python | |
| class ImmutablePoint: | |
| x: Final[int] | |
| y: Final[int] # Error: final attribute without an initializer | |
| def __init__(self) -> None: | |
| self.x = 1 # Good | |
| ``Final`` can only be used as the outermost type in assignments or variable | |
| annotations. Using it in any other position is an error. In particular, | |
| ``Final`` can't be used in annotations for function arguments: | |
| .. code-block:: python | |
| x: list[Final[int]] = [] # Error! | |
| def fun(x: Final[list[int]]) -> None: # Error! | |
| ... | |
| ``Final`` and :py:data:`~typing.ClassVar` should not be used together. Mypy will infer | |
| the scope of a final declaration automatically depending on whether it was | |
| initialized in the class body or in :py:meth:`__init__ <object.__init__>`. | |
| A final attribute can't be overridden by a subclass (even with another | |
| explicit final declaration). Note, however, that a final attribute can | |
| override a read-only property: | |
| .. code-block:: python | |
| class Base: | |
| @property | |
| def ID(self) -> int: ... | |
| class Derived(Base): | |
| ID: Final = 1 # OK | |
| Declaring a name as final only guarantees that the name will not be re-bound | |
| to another value. It doesn't make the value immutable. You can use immutable ABCs | |
| and containers to prevent mutating such values: | |
| .. code-block:: python | |
| x: Final = ['a', 'b'] | |
| x.append('c') # OK | |
| y: Final[Sequence[str]] = ['a', 'b'] | |
| y.append('x') # Error: Sequence is immutable | |
| z: Final = ('a', 'b') # Also an option | |
| Final methods | |
| ------------- | |
| Like with attributes, sometimes it is useful to protect a method from | |
| overriding. You can use the ``typing.final`` decorator for this purpose: | |
| .. code-block:: python | |
| from typing import final | |
| class Base: | |
| @final | |
| def common_name(self) -> None: | |
| ... | |
| class Derived(Base): | |
| def common_name(self) -> None: # Error: cannot override a final method | |
| ... | |
| This ``@final`` decorator can be used with instance methods, class methods, | |
| static methods, and properties. | |
| For overloaded methods, you should add ``@final`` on the implementation | |
| to make it final (or on the first overload in stubs): | |
| .. code-block:: python | |
| from typing import final, overload | |
| class Base: | |
| @overload | |
| def method(self) -> None: ... | |
| @overload | |
| def method(self, arg: int) -> int: ... | |
| @final | |
| def method(self, x=None): | |
| ... | |
| Final classes | |
| ------------- | |
| You can apply the ``typing.final`` decorator to a class to indicate | |
| to mypy that it should not be subclassed: | |
| .. code-block:: python | |
| from typing import final | |
| @final | |
| class Leaf: | |
| ... | |
| class MyLeaf(Leaf): # Error: Leaf can't be subclassed | |
| ... | |
| The decorator acts as a declaration for mypy (and as documentation for | |
| humans), but it doesn't actually prevent subclassing at runtime. | |
| Here are some situations where using a final class may be useful: | |
| * A class wasn't designed to be subclassed. Perhaps subclassing would not | |
| work as expected, or subclassing would be error-prone. | |
| * Subclassing would make code harder to understand or maintain. | |
| For example, you may want to prevent unnecessarily tight coupling between | |
| base classes and subclasses. | |
| * You want to retain the freedom to arbitrarily change the class implementation | |
| in the future, and these changes might break subclasses. | |
| An abstract class that defines at least one abstract method or | |
| property and has ``@final`` decorator will generate an error from | |
| mypy since those attributes could never be implemented. | |
| .. code-block:: python | |
| from abc import ABCMeta, abstractmethod | |
| from typing import final | |
| @final | |
| class A(metaclass=ABCMeta): # error: Final class A has abstract attributes "f" | |
| @abstractmethod | |
| def f(self, x: int) -> None: pass |