Skip to content

fix: allow Final[T] instance fields in dataclasses to depend on type variables#21643

Open
adhavan18 wants to merge 1 commit into
python:masterfrom
adhavan18:fix/final-typevar-in-dataclass-instance-field
Open

fix: allow Final[T] instance fields in dataclasses to depend on type variables#21643
adhavan18 wants to merge 1 commit into
python:masterfrom
adhavan18:fix/final-typevar-in-dataclass-instance-field

Conversation

@adhavan18

Copy link
Copy Markdown

Summary

Fixes #21637.

Final[T] fields in a @dataclass body are instance attributes, not class attributes (PEP 591 / dataclass spec: "A Final dataclass field initialized in the class body is not a class attribute unless explicitly annotated with ClassVar."). The checker was unconditionally raising Final name declared in class body cannot depend on type variables for any Final[T] in a generic class body.

Before:

from dataclasses import dataclass
from typing import Final, Generic, TypeVar

T = TypeVar("T")

@dataclass(frozen=True)
class A(Generic[T]):
    value: Final[T]  # error: Final name declared in class body cannot depend on type variables

After: no error (same behaviour as value: T without Final).

Change

In mypy/checker.py, the condition that raises DEPENDENT_FINAL_IN_CLASS_BODY now skips the error when:

  1. the active class has dataclass_tag in its metadata (i.e. it is a dataclass or dataclass-transform class), and
  2. the lvalue is a Var that is not marked is_classvar.

Plain (non-dataclass) classes and explicit ClassVar fields are unaffected.

Tests

Two new test cases in test-data/unit/check-final.test:

  • testFinalDefiningTypevarsDataclassInstanceFieldFinal[T] instance field in a frozen generic dataclass must not produce an error.
  • testFinalDefiningTypevarsNonDataclassStillErrorsFinal[T] in a plain generic class must still produce the error.

All 83 existing check-final tests pass with no regressions.

…variables

PEP 591 and the dataclass spec say that a Final field declared in a
dataclass body is an *instance attribute*, not a class attribute, unless
explicitly annotated with ClassVar. The checker was unconditionally
raising 'Final name declared in class body cannot depend on type
variables' for any Final[T] in a generic class body, which is correct
for plain classes but wrong for dataclasses.

fix: when the active class has 'dataclass_tag' in its metadata and the
lvalue is a Var that is not marked is_classvar, skip the error.
non-dataclass classes and explicit ClassVar fields are unaffected.

fixes python#21637
@github-actions

Copy link
Copy Markdown
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant