@@ -66,6 +66,8 @@ pub enum CallTarget {
66
66
BoundMethod ( Type , TargetWithTParams < Function > ) ,
67
67
/// A class object.
68
68
Class ( ClassType ) ,
69
+ /// A class object called via type[Self] (returns Self instead of ClassType).
70
+ SelfClass ( ClassType ) ,
69
71
/// A TypedDict.
70
72
TypedDict ( TypedDict ) ,
71
73
/// An overloaded function.
@@ -141,9 +143,8 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
141
143
Type :: ClassDef ( cls) => {
142
144
self . as_call_target_impl ( Type :: type_form ( self . instantiate ( & cls) ) , quantified)
143
145
}
144
- Type :: Type ( box Type :: ClassType ( cls) ) | Type :: Type ( box Type :: SelfType ( cls) ) => {
145
- Some ( CallTarget :: Class ( cls) )
146
- }
146
+ Type :: Type ( box Type :: ClassType ( cls) ) => Some ( CallTarget :: Class ( cls) ) ,
147
+ Type :: Type ( box Type :: SelfType ( cls) ) => Some ( CallTarget :: SelfClass ( cls) ) ,
147
148
Type :: Type ( box Type :: Tuple ( tuple) ) => {
148
149
Some ( CallTarget :: Class ( self . erase_tuple_type ( tuple) ) )
149
150
}
@@ -633,6 +634,47 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
633
634
} ;
634
635
self . construct_class ( cls, args, keywords, range, errors, context, hint)
635
636
}
637
+ CallTarget :: SelfClass ( cls) => {
638
+ if cls. has_qname ( "typing" , "Any" ) {
639
+ return self . error (
640
+ errors,
641
+ range,
642
+ ErrorInfo :: new ( ErrorKind :: BadInstantiation , context) ,
643
+ format ! ( "`{}` can not be instantiated" , cls. name( ) ) ,
644
+ ) ;
645
+ }
646
+ if self
647
+ . get_metadata_for_class ( cls. class_object ( ) )
648
+ . is_protocol ( )
649
+ {
650
+ self . error (
651
+ errors,
652
+ range,
653
+ ErrorInfo :: new ( ErrorKind :: BadInstantiation , context) ,
654
+ format ! (
655
+ "Cannot instantiate `{}` because it is a protocol" ,
656
+ cls. name( )
657
+ ) ,
658
+ ) ;
659
+ }
660
+ if cls. has_qname ( "builtins" , "bool" ) {
661
+ match self . first_arg_type ( args, errors) {
662
+ None => ( ) ,
663
+ Some ( ty) => self . check_dunder_bool_is_callable ( & ty, range, errors) ,
664
+ }
665
+ } ;
666
+ let result =
667
+ self . construct_class ( cls. clone ( ) , args, keywords, range, errors, context, hint) ;
668
+ // Handle custom __new__
669
+ match & result {
670
+ Type :: ClassType ( result_cls)
671
+ if result_cls. class_object ( ) == cls. class_object ( ) =>
672
+ {
673
+ Type :: SelfType ( result_cls. clone ( ) )
674
+ }
675
+ _ => result,
676
+ }
677
+ }
636
678
CallTarget :: TypedDict ( td) => {
637
679
self . construct_typed_dict ( td, args, keywords, range, errors, context, hint)
638
680
}
0 commit comments