@@ -2000,6 +2000,12 @@ impl<'db> Type<'db> {
20002000 ) )
20012001 . into ( ) ,
20022002 ) ,
2003+ ( Some ( KnownClass :: Str ) , "startswith" ) => Some (
2004+ Symbol :: bound ( Type :: WrapperDescriptor (
2005+ WrapperDescriptorKind :: StrStartswith ,
2006+ ) )
2007+ . into ( ) ,
2008+ ) ,
20032009 // TODO:
20042010 // We currently hard-code the knowledge that the following known classes are not
20052011 // descriptors, i.e. that they have no `__get__` method. This is not wrong and
@@ -2508,6 +2514,10 @@ impl<'db> Type<'db> {
25082514 Type :: MethodWrapper ( MethodWrapperKind :: PropertyDunderSet ( property) ) ,
25092515 )
25102516 . into ( ) ,
2517+ Type :: StringLiteral ( literal) if name == "startswith" => Symbol :: bound (
2518+ Type :: MethodWrapper ( MethodWrapperKind :: StrStartswith ( literal) ) ,
2519+ )
2520+ . into ( ) ,
25112521
25122522 Type :: ClassLiteral ( class)
25132523 if name == "__get__" && class. is_known ( db, KnownClass :: FunctionType ) =>
@@ -2533,6 +2543,14 @@ impl<'db> Type<'db> {
25332543 ) )
25342544 . into ( )
25352545 }
2546+ Type :: ClassLiteral ( class)
2547+ if name == "startswith" && class. is_known ( db, KnownClass :: Str ) =>
2548+ {
2549+ Symbol :: bound ( Type :: WrapperDescriptor (
2550+ WrapperDescriptorKind :: StrStartswith ,
2551+ ) )
2552+ . into ( )
2553+ }
25362554 Type :: BoundMethod ( bound_method) => match name_str {
25372555 "__self__" => Symbol :: bound ( bound_method. self_instance ( db) ) . into ( ) ,
25382556 "__func__" => {
@@ -3043,7 +3061,7 @@ impl<'db> Type<'db> {
30433061 WrapperDescriptorKind :: PropertyDunderGet => {
30443062 KnownClass :: Property . to_instance ( db)
30453063 }
3046- WrapperDescriptorKind :: PropertyDunderSet => {
3064+ _ => {
30473065 unreachable ! ( "Not part of outer match pattern" )
30483066 }
30493067 } ;
@@ -3112,6 +3130,34 @@ impl<'db> Type<'db> {
31123130 ) )
31133131 }
31143132
3133+ Type :: MethodWrapper ( MethodWrapperKind :: StrStartswith ( _) ) => {
3134+ Signatures :: single ( CallableSignature :: single (
3135+ self ,
3136+ Signature :: new (
3137+ Parameters :: new ( [
3138+ Parameter :: positional_only ( Some ( Name :: new_static ( "prefix" ) ) )
3139+ . with_annotated_type ( UnionType :: from_elements (
3140+ db,
3141+ [
3142+ KnownClass :: Str . to_instance ( db) ,
3143+ // TODO: tuple[str, ...]
3144+ KnownClass :: Tuple . to_instance ( db) ,
3145+ ] ,
3146+ ) ) ,
3147+ Parameter :: positional_only ( Some ( Name :: new_static ( "start" ) ) )
3148+ // TODO: SupportsIndex | None
3149+ . with_annotated_type ( Type :: object ( db) )
3150+ . with_default_type ( Type :: none ( db) ) ,
3151+ Parameter :: positional_only ( Some ( Name :: new_static ( "end" ) ) )
3152+ // TODO: SupportsIndex | None
3153+ . with_annotated_type ( Type :: object ( db) )
3154+ . with_default_type ( Type :: none ( db) ) ,
3155+ ] ) ,
3156+ Some ( KnownClass :: Bool . to_instance ( db) ) ,
3157+ ) ,
3158+ ) )
3159+ }
3160+
31153161 Type :: FunctionLiteral ( function_type) => match function_type. known ( db) {
31163162 Some (
31173163 KnownFunction :: IsEquivalentTo
@@ -4238,6 +4284,7 @@ impl<'db> Type<'db> {
42384284 | Type :: AlwaysTruthy
42394285 | Type :: AlwaysFalsy
42404286 | Type :: WrapperDescriptor ( _)
4287+ | Type :: MethodWrapper ( MethodWrapperKind :: StrStartswith ( _) )
42414288 | Type :: ModuleLiteral ( _)
42424289 // A non-generic class never needs to be specialized. A generic class is specialized
42434290 // explicitly (via a subscript expression) or implicitly (via a call), and not because
@@ -6155,6 +6202,8 @@ pub enum MethodWrapperKind<'db> {
61556202 PropertyDunderGet ( PropertyInstanceType < ' db > ) ,
61566203 /// Method wrapper for `some_property.__set__`
61576204 PropertyDunderSet ( PropertyInstanceType < ' db > ) ,
6205+ /// Method wrapper for `str.startswith`
6206+ StrStartswith ( StringLiteralType < ' db > ) ,
61586207}
61596208
61606209/// Represents a specific instance of `types.WrapperDescriptorType`
@@ -6166,6 +6215,8 @@ pub enum WrapperDescriptorKind {
61666215 PropertyDunderGet ,
61676216 /// `property.__set__`
61686217 PropertyDunderSet ,
6218+ /// `str.startswith`
6219+ StrStartswith ,
61696220}
61706221
61716222#[ salsa:: interned( debug) ]
0 commit comments