Model fallback MethodType => FunctionType
This commit is contained in:
@@ -89,6 +89,14 @@ If we access an attribute on a bound method object itself, it will defer to `typ
|
||||
reveal_type(bound_method.__hash__) # revealed: <bound method `__hash__` of `MethodType`>
|
||||
```
|
||||
|
||||
If an attribute is not available on the bound method object, it will be looked up on the underlying
|
||||
function object. We model this explicitly, which means that we can access `__module__` on bound
|
||||
methods, even though it is not available on `types.MethodType`:
|
||||
|
||||
```py
|
||||
reveal_type(bound_method.__module__) # revealed: str
|
||||
```
|
||||
|
||||
## Basic method calls on class objects and instances
|
||||
|
||||
```py
|
||||
|
||||
@@ -1607,7 +1607,17 @@ impl<'db> Type<'db> {
|
||||
Type::Callable(CallableType::BoundMethod(bound_method)) => match name {
|
||||
"__self__" => Symbol::bound(bound_method.self_instance(db)),
|
||||
"__func__" => Symbol::bound(Type::FunctionLiteral(bound_method.function(db))),
|
||||
_ => KnownClass::MethodType.to_instance(db).member(db, name),
|
||||
_ => {
|
||||
let member = KnownClass::MethodType.to_instance(db).member(db, name);
|
||||
|
||||
// If an attribute is not available on the bound method object, it will be looked
|
||||
// up on the underlying function object:
|
||||
if member.is_unbound() {
|
||||
Type::FunctionLiteral(bound_method.function(db)).member(db, name)
|
||||
} else {
|
||||
member
|
||||
}
|
||||
}
|
||||
},
|
||||
Type::Callable(CallableType::MethodWrapperDunderGet(_)) => {
|
||||
KnownClass::MethodWrapperType
|
||||
@@ -3747,7 +3757,7 @@ impl KnownFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/// This type represents bound method objects that are created when a method is called
|
||||
/// This type represents bound method objects that are created when a method is accessed
|
||||
/// on an instance of a class. For example, the expression `Path("a.txt").touch` creates
|
||||
/// a bound method object that represents the `Path.touch` method which is bound to the
|
||||
/// instance `Path("a.txt")`.
|
||||
|
||||
Reference in New Issue
Block a user