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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False positive for Final attributes using typevars in dataclasses

1 participant