@@ -594,12 +594,13 @@ pub enum PropertyAccessorRole {
594594 Deleter ,
595595}
596596
597- /// Represents an instance of `builtins.property`.
598- #[ salsa:: interned( debug, heap_size=ruff_memory_usage:: heap_size) ]
597+ /// Represents an instance of `builtins.property` or `enum.property` .
598+ #[ salsa:: interned( debug, constructor=new_internal , heap_size=ruff_memory_usage:: heap_size) ]
599599pub struct PropertyInstanceType < ' db > {
600600 pub getter : Option < Type < ' db > > ,
601601 pub setter : Option < Type < ' db > > ,
602602 pub deleter : Option < Type < ' db > > ,
603+ instance_class : KnownClass ,
603604}
604605
605606fn walk_property_instance_type < ' db , V : visitor:: TypeVisitor < ' db > + ?Sized > (
@@ -622,6 +623,38 @@ fn walk_property_instance_type<'db, V: visitor::TypeVisitor<'db> + ?Sized>(
622623impl get_size2:: GetSize for PropertyInstanceType < ' _ > { }
623624
624625impl < ' db > PropertyInstanceType < ' db > {
626+ pub fn new (
627+ db : & ' db dyn Db ,
628+ getter : Option < Type < ' db > > ,
629+ setter : Option < Type < ' db > > ,
630+ deleter : Option < Type < ' db > > ,
631+ ) -> Self {
632+ Self :: new_internal ( db, getter, setter, deleter, KnownClass :: Property )
633+ }
634+
635+ fn new_enum_property (
636+ db : & ' db dyn Db ,
637+ getter : Option < Type < ' db > > ,
638+ setter : Option < Type < ' db > > ,
639+ deleter : Option < Type < ' db > > ,
640+ ) -> Self {
641+ Self :: new_internal ( db, getter, setter, deleter, KnownClass :: EnumProperty )
642+ }
643+
644+ fn with_accessors (
645+ self ,
646+ db : & ' db dyn Db ,
647+ getter : Option < Type < ' db > > ,
648+ setter : Option < Type < ' db > > ,
649+ deleter : Option < Type < ' db > > ,
650+ ) -> Self {
651+ Self :: new_internal ( db, getter, setter, deleter, self . instance_class ( db) )
652+ }
653+
654+ fn instance_fallback ( self , db : & ' db dyn Db ) -> Type < ' db > {
655+ self . instance_class ( db) . to_instance ( db)
656+ }
657+
625658 /// Returns the [`PropertyAccessorRole`] that `def` plays in this property, or `None` when
626659 /// `def` is not one of this property's accessors.
627660 ///
@@ -669,7 +702,7 @@ impl<'db> PropertyInstanceType<'db> {
669702 let deleter = self
670703 . deleter ( db)
671704 . map ( |ty| ty. apply_type_mapping_impl ( db, type_mapping, tcx, visitor) ) ;
672- Self :: new ( db, getter, setter, deleter)
705+ self . with_accessors ( db, getter, setter, deleter)
673706 }
674707
675708 fn recursive_type_normalized_impl (
@@ -702,7 +735,7 @@ impl<'db> PropertyInstanceType<'db> {
702735 ) ,
703736 None => None ,
704737 } ;
705- Some ( Self :: new ( db, getter, setter, deleter) )
738+ Some ( self . with_accessors ( db, getter, setter, deleter) )
706739 }
707740
708741 fn find_legacy_typevars_impl (
@@ -1369,6 +1402,7 @@ impl<'db> Type<'db> {
13691402 bound. nominal_class ( db)
13701403 }
13711404 Type :: LiteralValue ( literal) => literal. fallback_instance ( db) . nominal_class ( db) ,
1405+ Type :: PropertyInstance ( property) => property. instance_fallback ( db) . nominal_class ( db) ,
13721406 _ => None ,
13731407 }
13741408 }
@@ -2538,13 +2572,13 @@ impl<'db> Type<'db> {
25382572 // Hard code this knowledge, as we look up `__set__` and `__delete__` on `FunctionType` often.
25392573 Some ( Place :: Undefined . into ( ) )
25402574 }
2541- ( Some ( KnownClass :: Property ) , "__get__" ) => Some (
2575+ ( Some ( KnownClass :: Property | KnownClass :: EnumProperty ) , "__get__" ) => Some (
25422576 Place :: bound ( Type :: WrapperDescriptor (
25432577 WrapperDescriptorKind :: PropertyDunderGet ,
25442578 ) )
25452579 . into ( ) ,
25462580 ) ,
2547- ( Some ( KnownClass :: Property ) , "__set__" ) => Some (
2581+ ( Some ( KnownClass :: Property | KnownClass :: EnumProperty ) , "__set__" ) => Some (
25482582 Place :: bound ( Type :: WrapperDescriptor (
25492583 WrapperDescriptorKind :: PropertyDunderSet ,
25502584 ) )
@@ -2887,9 +2921,9 @@ impl<'db> Type<'db> {
28872921
28882922 Type :: SpecialForm ( _) | Type :: KnownInstance ( _) => Place :: Undefined . into ( ) ,
28892923
2890- Type :: PropertyInstance ( _ ) => KnownClass :: Property
2891- . to_instance ( db)
2892- . instance_member ( db , name ) ,
2924+ Type :: PropertyInstance ( property ) => {
2925+ property . instance_fallback ( db) . instance_member ( db , name )
2926+ }
28932927
28942928 // Note: `super(pivot, owner).__dict__` refers to the `__dict__` of the `builtins.super` instance,
28952929 // not that of the owner.
@@ -5804,7 +5838,7 @@ impl<'db> Type<'db> {
58045838 Type :: NominalInstance ( instance) => instance. to_meta_type ( db) ,
58055839 Type :: KnownInstance ( known_instance) => known_instance. to_meta_type ( db) ,
58065840 Type :: SpecialForm ( special_form) => special_form. to_meta_type ( db) ,
5807- Type :: PropertyInstance ( _ ) => KnownClass :: Property . to_class_literal ( db) ,
5841+ Type :: PropertyInstance ( property ) => property . instance_class ( db ) . to_class_literal ( db) ,
58085842 Type :: Union ( union) => union. map ( db, |ty| ty. to_meta_type ( db) ) ,
58095843 Type :: TypeIs ( _) | Type :: TypeGuard ( _) => KnownClass :: Bool . to_class_literal ( db) ,
58105844 Type :: TypeForm ( _) => Type :: object ( ) . to_meta_type ( db) ,
0 commit comments