@@ -2000,6 +2000,7 @@ impl<'db> Type<'db> {
20002000 ) )
20012001 . into ( ) ,
20022002 ) ,
2003+
20032004 // TODO:
20042005 // We currently hard-code the knowledge that the following known classes are not
20052006 // descriptors, i.e. that they have no `__get__` method. This is not wrong and
@@ -2508,6 +2509,10 @@ impl<'db> Type<'db> {
25082509 Type :: MethodWrapper ( MethodWrapperKind :: PropertyDunderSet ( property) ) ,
25092510 )
25102511 . into ( ) ,
2512+ Type :: StringLiteral ( literal) if name == "startswith" => Symbol :: bound (
2513+ Type :: MethodWrapper ( MethodWrapperKind :: StrStartswith ( literal) ) ,
2514+ )
2515+ . into ( ) ,
25112516
25122517 Type :: ClassLiteral ( class)
25132518 if name == "__get__" && class. is_known ( db, KnownClass :: FunctionType ) =>
@@ -3043,7 +3048,7 @@ impl<'db> Type<'db> {
30433048 WrapperDescriptorKind :: PropertyDunderGet => {
30443049 KnownClass :: Property . to_instance ( db)
30453050 }
3046- WrapperDescriptorKind :: PropertyDunderSet => {
3051+ _ => {
30473052 unreachable ! ( "Not part of outer match pattern" )
30483053 }
30493054 } ;
@@ -3112,6 +3117,34 @@ impl<'db> Type<'db> {
31123117 ) )
31133118 }
31143119
3120+ Type :: MethodWrapper ( MethodWrapperKind :: StrStartswith ( _) ) => {
3121+ Signatures :: single ( CallableSignature :: single (
3122+ self ,
3123+ Signature :: new (
3124+ Parameters :: new ( [
3125+ Parameter :: positional_only ( Some ( Name :: new_static ( "prefix" ) ) )
3126+ . with_annotated_type ( UnionType :: from_elements (
3127+ db,
3128+ [
3129+ KnownClass :: Str . to_instance ( db) ,
3130+ // TODO: tuple[str, ...]
3131+ KnownClass :: Tuple . to_instance ( db) ,
3132+ ] ,
3133+ ) ) ,
3134+ Parameter :: positional_only ( Some ( Name :: new_static ( "start" ) ) )
3135+ // TODO: SupportsIndex | None
3136+ . with_annotated_type ( Type :: object ( db) )
3137+ . with_default_type ( Type :: none ( db) ) ,
3138+ Parameter :: positional_only ( Some ( Name :: new_static ( "end" ) ) )
3139+ // TODO: SupportsIndex | None
3140+ . with_annotated_type ( Type :: object ( db) )
3141+ . with_default_type ( Type :: none ( db) ) ,
3142+ ] ) ,
3143+ Some ( KnownClass :: Bool . to_instance ( db) ) ,
3144+ ) ,
3145+ ) )
3146+ }
3147+
31153148 Type :: FunctionLiteral ( function_type) => match function_type. known ( db) {
31163149 Some (
31173150 KnownFunction :: IsEquivalentTo
@@ -4238,6 +4271,7 @@ impl<'db> Type<'db> {
42384271 | Type :: AlwaysTruthy
42394272 | Type :: AlwaysFalsy
42404273 | Type :: WrapperDescriptor ( _)
4274+ | Type :: MethodWrapper ( MethodWrapperKind :: StrStartswith ( _) )
42414275 | Type :: ModuleLiteral ( _)
42424276 // A non-generic class never needs to be specialized. A generic class is specialized
42434277 // explicitly (via a subscript expression) or implicitly (via a call), and not because
@@ -6155,6 +6189,8 @@ pub enum MethodWrapperKind<'db> {
61556189 PropertyDunderGet ( PropertyInstanceType < ' db > ) ,
61566190 /// Method wrapper for `some_property.__set__`
61576191 PropertyDunderSet ( PropertyInstanceType < ' db > ) ,
6192+ /// Method wrapper for `str.startswith`
6193+ StrStartswith ( StringLiteralType < ' db > ) ,
61586194}
61596195
61606196/// Represents a specific instance of `types.WrapperDescriptorType`
0 commit comments