Treat @staticmethod as higher-precedence than ABC (#2635)

This commit is contained in:
Charlie Marsh 2023-02-07 14:57:03 -05:00 committed by GitHub
parent 2bc16eb4e3
commit 8ee51eb5c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 12 deletions

View file

@ -46,6 +46,10 @@ class MetaClass(ABCMeta):
def good_method(cls):
pass
@staticmethod
def static_method(not_cls) -> bool:
return False
def func(x):
return x

View file

@ -26,8 +26,18 @@ pub fn classify(
let ScopeKind::Class(scope) = &scope.kind else {
return FunctionType::Function;
};
// Special-case class method, like `__new__`.
if CLASS_METHODS.contains(&name)
if decorator_list.iter().any(|expr| {
// The method is decorated with a static method decorator (like
// `@staticmethod`).
checker.resolve_call_path(expr).map_or(false, |call_path| {
staticmethod_decorators
.iter()
.any(|decorator| call_path == to_call_path(decorator))
})
}) {
FunctionType::StaticMethod
} else if CLASS_METHODS.contains(&name)
// Special-case class method, like `__new__`.
|| scope.bases.iter().any(|expr| {
// The class itself extends a known metaclass, so all methods are class methods.
checker.resolve_call_path(expr).map_or(false, |call_path| {
@ -46,16 +56,6 @@ pub fn classify(
})
{
FunctionType::ClassMethod
} else if decorator_list.iter().any(|expr| {
// The method is decorated with a static method decorator (like
// `@staticmethod`).
checker.resolve_call_path(expr).map_or(false, |call_path| {
staticmethod_decorators
.iter()
.any(|decorator| call_path == to_call_path(decorator))
})
}) {
FunctionType::StaticMethod
} else {
// It's an instance method.
FunctionType::Method