Skip to content

Constant should be Final inspection

Report module-level constants that look immutable but are missing a Final[...] annotation. The quick-fix adds the annotation and inserts the required import so the declaration becomes explicit to readers and type checkers.

How to invoke

Enable the inspection and place the caret on a reported constant, then use ⌥⏎ / Alt+Enter"Wrap constant type in Final".

Example

API_VERSION = "v1"

becomes:

from typing import Final

API_VERSION: Final[str] = "v1"

What it supports

  • Module-level constants with a single simple target such as NAME = value.
  • Literal values, inferred class types, unions, and collection types when building the Final[...] annotation.
  • Existing typing_extensions.Final imports.
  • None initializers, which become Final[None].
  • Imported module qualification when an inferred type would otherwise be ambiguous.

What it deliberately avoids

  • Multi-target assignments such as A = B = 1.
  • Qualified targets such as obj.NAME = value.
  • Constants inside enum classes.
  • Assignments already annotated with Final.
  • Typing special forms such as TypeVar, ParamSpec, TypeVarTuple, and NewType.

Notes

  • The inspection only runs on your own project files, not library or stub sources.
  • The feature is gated by the Constant should be Final inspection setting under Settings | BetterPy | Code Quality & Safety | Code Inspections and is enabled by default.
  • The quick-fix preserves the original assigned expression and reformats the final statement through the IDE code style manager.