Skip to content

Commit 7409a97

Browse files
asukaminato0721meta-codesync[bot]
authored andcommitted
fix False positive with @DataClass(frozen=True) and a ClassVar #2789 (#2792)
Summary: Fixes #2789 stops ClassVar members from being classified as frozen dataclass fields. preserves the existing ClassVar write restriction on instances, but no longer incorrectly rejects writes through a class object like `self.__class__.x = False` in a frozen dataclass. Pull Request resolved: #2792 Test Plan: add test Reviewed By: grievejia Differential Revision: D96812149 Pulled By: rchen152 fbshipit-source-id: 467eac510e0a47f519c32a23db99f03dc4d12b3a
1 parent 6d21b41 commit 7409a97

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

pyrefly/lib/alt/class/class_field.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,9 +2118,12 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
21182118
{
21192119
return Some(ReadOnlyReason::NamedTuple);
21202120
}
2121+
// ClassVars in dataclasses are class attributes rather than frozen instance fields.
2122+
let is_classvar = annotation.is_some_and(|ann| ann.has_qualifier(&Qualifier::ClassVar));
21212123
// Frozen dataclass fields (not methods) are read-only
21222124
if let Some(dm) = metadata.dataclass_metadata()
21232125
&& dm.kws.frozen
2126+
&& !is_classvar
21242127
&& dm.fields.contains(name)
21252128
{
21262129
let reason = if metadata.is_pydantic_model() {

pyrefly/lib/test/dataclasses.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,21 @@ C()
792792
"#,
793793
);
794794

795+
testcase!(
796+
test_frozen_classvar_class_assignment,
797+
r#"
798+
import dataclasses
799+
from typing import ClassVar
800+
801+
@dataclasses.dataclass(frozen=True)
802+
class C:
803+
x: ClassVar[bool] = True
804+
805+
def set_x(self) -> None:
806+
self.__class__.x = False
807+
"#,
808+
);
809+
795810
testcase!(
796811
test_hashable,
797812
r#"

0 commit comments

Comments
 (0)