File tree Expand file tree Collapse file tree 2 files changed +52
-1
lines changed
crates/ty_python_semantic
resources/mdtest/dataclasses Expand file tree Collapse file tree 2 files changed +52
-1
lines changed Original file line number Diff line number Diff line change @@ -425,7 +425,39 @@ from dataclasses import dataclass
425425class MyFrozenClass : ...
426426
427427frozen = MyFrozenClass()
428- frozen.x = 2 # error: [unresolved-attribute]
428+ frozen.x = 2 # error: [invalid-assignment]
429+ ```
430+
431+ diagnostic is also emitted if a frozen dataclass is inherited, and an attempt is made to mutate an
432+ attribute in the child class:
433+
434+ ``` py
435+ from dataclasses import dataclass
436+
437+ @dataclass (frozen = True )
438+ class MyFrozenClass :
439+ x: int = 1
440+
441+ class MyFrozenChildClass (MyFrozenClass ): ...
442+
443+ frozen = MyFrozenChildClass()
444+ frozen.x = 2 # error: [invalid-assignment]
445+ ```
446+
447+ The same diagnostic is emitted if a frozen dataclass is inherited, and an attempt is made to delete
448+ an attribute:
449+
450+ ``` py
451+ from dataclasses import dataclass
452+
453+ @dataclass (frozen = True )
454+ class MyFrozenClass :
455+ x: int = 1
456+
457+ class MyFrozenChildClass (MyFrozenClass ): ...
458+
459+ frozen = MyFrozenChildClass()
460+ del frozen.x # TODO this should emit an [invalid-assignment]
429461```
430462
431463### ` match_args `
Original file line number Diff line number Diff line change @@ -1589,6 +1589,25 @@ impl<'db> ClassLiteral<'db> {
15891589 . place
15901590 . ignore_possibly_unbound ( )
15911591 }
1592+ ( CodeGeneratorKind :: DataclassLike , "__setattr__" ) => {
1593+ if has_dataclass_param ( DataclassParams :: FROZEN ) {
1594+ let signature = Signature :: new (
1595+ Parameters :: new ( [
1596+ Parameter :: positional_or_keyword ( Name :: new_static ( "self" ) )
1597+ . with_annotated_type ( Type :: instance (
1598+ db,
1599+ self . apply_optional_specialization ( db, specialization) ,
1600+ ) ) ,
1601+ Parameter :: positional_or_keyword ( Name :: new_static ( "name" ) ) ,
1602+ Parameter :: positional_or_keyword ( Name :: new_static ( "value" ) ) ,
1603+ ] ) ,
1604+ Some ( Type :: Never ) ,
1605+ ) ;
1606+
1607+ return Some ( CallableType :: function_like ( db, signature) ) ;
1608+ }
1609+ None
1610+ }
15921611 _ => None ,
15931612 }
15941613 }
You can’t perform that action at this time.
0 commit comments