From 9a4b85d8456fbd152ae7f7ff149f27ac43e0ea00 Mon Sep 17 00:00:00 2001 From: David Peter Date: Tue, 8 Jul 2025 14:33:46 +0200 Subject: [PATCH] [ty] Add tests for dataclass fields annotated with `Final` (#19202) ## Summary Adds some tests for dataclass fields that are annotated with `Final` (see comment [here](https://github.com/astral-sh/ruff/pull/15768#issuecomment-3044737645)). Turns out that nothing is needed here, everything already works as expected (apart from the fact that we can assign to `Final` fields, which is tracked in https://github.com/astral-sh/ty/issues/158 ## Test Plan New Markdown tests --- .../mdtest/dataclasses/dataclasses.md | 27 +++++++++++++++++++ .../resources/mdtest/type_qualifiers/final.md | 4 +++ 2 files changed, 31 insertions(+) diff --git a/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md b/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md index 7ed6ea8962..77a6b22ca0 100644 --- a/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md +++ b/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md @@ -444,6 +444,33 @@ To do To do +## `Final` fields + +Dataclass fields can be annotated with `Final`, which means that the field cannot be reassigned +after the instance is created. Fields that are additionally annotated with `ClassVar` are not part +of the `__init__` signature. + +```py +from dataclasses import dataclass +from typing import Final, ClassVar + +@dataclass +class C: + # a `Final` annotation without a right-hand side is not allowed in normal classes, + # but valid for dataclasses. The field will be initialized in the synthesized + # `__init__` method + instance_variable_no_default: Final[int] + instance_variable: Final[int] = 1 + class_variable1: ClassVar[Final[int]] = 1 + class_variable2: ClassVar[Final[int]] = 1 + +reveal_type(C.__init__) # revealed: (self: C, instance_variable_no_default: int, instance_variable: int = Literal[1]) -> None + +c = C(1) +# TODO: this should be an error +c.instance_variable = 2 +``` + ## Inheritance ### Normal class inheriting from a dataclass diff --git a/crates/ty_python_semantic/resources/mdtest/type_qualifiers/final.md b/crates/ty_python_semantic/resources/mdtest/type_qualifiers/final.md index da1398b1ab..224115f942 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_qualifiers/final.md +++ b/crates/ty_python_semantic/resources/mdtest/type_qualifiers/final.md @@ -162,6 +162,10 @@ from typing import Final # TODO: This should be an error NO_RHS: Final + +class C: + # TODO: This should be an error + NO_RHS: Final ``` [`typing.final`]: https://docs.python.org/3/library/typing.html#typing.Final