@@ -3442,20 +3442,6 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
34423442 | Type :: AlwaysTruthy
34433443 | Type :: AlwaysFalsy
34443444 | Type :: TypeIs ( _) => {
3445- let is_read_only = || {
3446- let dataclass_params = match object_ty {
3447- Type :: NominalInstance ( instance) => match instance. class {
3448- ClassType :: NonGeneric ( cls) => cls. dataclass_params ( self . db ( ) ) ,
3449- ClassType :: Generic ( cls) => {
3450- cls. origin ( self . db ( ) ) . dataclass_params ( self . db ( ) )
3451- }
3452- } ,
3453- _ => None ,
3454- } ;
3455-
3456- dataclass_params. is_some_and ( |params| params. contains ( DataclassParams :: FROZEN ) )
3457- } ;
3458-
34593445 // First, try to call the `__setattr__` dunder method. If this is present/defined, overrides
34603446 // assigning the attributed by the normal mechanism.
34613447 let setattr_dunder_call_result = object_ty. try_call_dunder_with_policy (
@@ -3529,85 +3515,71 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
35293515 place : Place :: Type ( meta_attr_ty, meta_attr_boundness) ,
35303516 qualifiers : _,
35313517 } => {
3532- if is_read_only ( ) {
3533- if emit_diagnostics {
3534- if let Some ( builder) =
3535- self . context . report_lint ( & INVALID_ASSIGNMENT , target)
3536- {
3537- builder. into_diagnostic ( format_args ! (
3538- "Property `{attribute}` defined in `{ty}` is read-only" ,
3539- ty = object_ty. display( self . db( ) ) ,
3540- ) ) ;
3541- }
3542- }
3543- false
3544- } else {
3545- let assignable_to_meta_attr =
3546- if let Place :: Type ( meta_dunder_set, _) =
3547- meta_attr_ty. class_member ( db, "__set__" . into ( ) ) . place
3548- {
3549- let successful_call = meta_dunder_set
3550- . try_call (
3551- db,
3552- & CallArgumentTypes :: positional ( [
3553- meta_attr_ty,
3554- object_ty,
3555- value_ty,
3556- ] ) ,
3557- )
3558- . is_ok ( ) ;
3559-
3560- if !successful_call && emit_diagnostics {
3561- if let Some ( builder) = self
3562- . context
3563- . report_lint ( & INVALID_ASSIGNMENT , target)
3564- {
3565- // TODO: Here, it would be nice to emit an additional diagnostic that explains why the call failed
3566- builder. into_diagnostic ( format_args ! (
3518+ let assignable_to_meta_attr =
3519+ if let Place :: Type ( meta_dunder_set, _) =
3520+ meta_attr_ty. class_member ( db, "__set__" . into ( ) ) . place
3521+ {
3522+ let successful_call = meta_dunder_set
3523+ . try_call (
3524+ db,
3525+ & CallArgumentTypes :: positional ( [
3526+ meta_attr_ty,
3527+ object_ty,
3528+ value_ty,
3529+ ] ) ,
3530+ )
3531+ . is_ok ( ) ;
3532+
3533+ if !successful_call && emit_diagnostics {
3534+ if let Some ( builder) = self
3535+ . context
3536+ . report_lint ( & INVALID_ASSIGNMENT , target)
3537+ {
3538+ // TODO: Here, it would be nice to emit an additional diagnostic that explains why the call failed
3539+ builder. into_diagnostic ( format_args ! (
35673540 "Invalid assignment to data descriptor attribute \
35683541 `{attribute}` on type `{}` with custom `__set__` method",
35693542 object_ty. display( db)
35703543 ) ) ;
3571- }
35723544 }
3545+ }
35733546
3574- successful_call
3547+ successful_call
3548+ } else {
3549+ ensure_assignable_to ( meta_attr_ty)
3550+ } ;
3551+
3552+ let assignable_to_instance_attribute =
3553+ if meta_attr_boundness == Boundness :: PossiblyUnbound {
3554+ let ( assignable, boundness) = if let Place :: Type (
3555+ instance_attr_ty,
3556+ instance_attr_boundness,
3557+ ) =
3558+ object_ty. instance_member ( db, attribute) . place
3559+ {
3560+ (
3561+ ensure_assignable_to ( instance_attr_ty) ,
3562+ instance_attr_boundness,
3563+ )
35753564 } else {
3576- ensure_assignable_to ( meta_attr_ty )
3565+ ( true , Boundness :: PossiblyUnbound )
35773566 } ;
35783567
3579- let assignable_to_instance_attribute =
3580- if meta_attr_boundness == Boundness :: PossiblyUnbound {
3581- let ( assignable, boundness) = if let Place :: Type (
3582- instance_attr_ty,
3583- instance_attr_boundness,
3584- ) =
3585- object_ty. instance_member ( db, attribute) . place
3586- {
3587- (
3588- ensure_assignable_to ( instance_attr_ty) ,
3589- instance_attr_boundness,
3590- )
3591- } else {
3592- ( true , Boundness :: PossiblyUnbound )
3593- } ;
3594-
3595- if boundness == Boundness :: PossiblyUnbound {
3596- report_possibly_unbound_attribute (
3597- & self . context ,
3598- target,
3599- attribute,
3600- object_ty,
3601- ) ;
3602- }
3568+ if boundness == Boundness :: PossiblyUnbound {
3569+ report_possibly_unbound_attribute (
3570+ & self . context ,
3571+ target,
3572+ attribute,
3573+ object_ty,
3574+ ) ;
3575+ }
36033576
3604- assignable
3605- } else {
3606- true
3607- } ;
3577+ assignable
3578+ } else {
3579+ true
3580+ } ;
36083581
3609- assignable_to_meta_attr && assignable_to_instance_attribute
3610- }
3582+ assignable_to_meta_attr && assignable_to_instance_attribute
36113583 }
36123584
36133585 PlaceAndQualifiers {
@@ -3626,22 +3598,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
36263598 ) ;
36273599 }
36283600
3629- if is_read_only ( ) {
3630- if emit_diagnostics {
3631- if let Some ( builder) = self
3632- . context
3633- . report_lint ( & INVALID_ASSIGNMENT , target)
3634- {
3635- builder. into_diagnostic ( format_args ! (
3636- "Property `{attribute}` defined in `{ty}` is read-only" ,
3637- ty = object_ty. display( self . db( ) ) ,
3638- ) ) ;
3639- }
3640- }
3641- false
3642- } else {
3643- ensure_assignable_to ( instance_attr_ty)
3644- }
3601+ ensure_assignable_to ( instance_attr_ty)
36453602 } else {
36463603 if emit_diagnostics {
36473604 if let Some ( builder) =
0 commit comments