diff --git a/crates/ty_python_semantic/src/types/call/bind.rs b/crates/ty_python_semantic/src/types/call/bind.rs index f9665cfc98..17bec1416b 100644 --- a/crates/ty_python_semantic/src/types/call/bind.rs +++ b/crates/ty_python_semantic/src/types/call/bind.rs @@ -290,8 +290,7 @@ impl<'db> Bindings<'db> { } _ => {} } - } else if function.has_known_decorator(db, FunctionDecorators::STATICMETHOD) - { + } else if function.is_staticmethod(db) { overload.set_return_type(Type::FunctionLiteral(function)); } else if let [Some(first), _] = overload.parameter_types() { if first.is_none(db) { diff --git a/crates/ty_python_semantic/src/types/class.rs b/crates/ty_python_semantic/src/types/class.rs index d678e749a2..1dbe288b3c 100644 --- a/crates/ty_python_semantic/src/types/class.rs +++ b/crates/ty_python_semantic/src/types/class.rs @@ -3,10 +3,8 @@ use std::sync::{LazyLock, Mutex}; use super::TypeVarVariance; use super::{ BoundTypeVarInstance, IntersectionBuilder, MemberLookupPolicy, Mro, MroError, MroIterator, - SpecialFormType, SubclassOfType, Truthiness, Type, TypeQualifiers, - class_base::ClassBase, - function::{FunctionDecorators, FunctionType}, - infer_expression_type, infer_unpack_types, + SpecialFormType, SubclassOfType, Truthiness, Type, TypeQualifiers, class_base::ClassBase, + function::FunctionType, infer_expression_type, infer_unpack_types, }; use crate::FxOrderMap; use crate::module_resolver::KnownModule; @@ -1257,10 +1255,7 @@ pub(super) enum MethodDecorator { impl MethodDecorator { fn try_from_fn_type(db: &dyn Db, fn_type: FunctionType) -> Result { - match ( - fn_type.is_classmethod(db), - fn_type.has_known_decorator(db, FunctionDecorators::STATICMETHOD), - ) { + match (fn_type.is_classmethod(db), fn_type.is_staticmethod(db)) { (true, true) => Err(()), // A method can't be static and class method at the same time. (true, false) => Ok(Self::ClassMethod), (false, true) => Ok(Self::StaticMethod), diff --git a/crates/ty_python_semantic/src/types/function.rs b/crates/ty_python_semantic/src/types/function.rs index 3730439017..a6357d145e 100644 --- a/crates/ty_python_semantic/src/types/function.rs +++ b/crates/ty_python_semantic/src/types/function.rs @@ -731,6 +731,12 @@ impl<'db> FunctionType<'db> { ) } + /// Returns true if this method is decorated with `@staticmethod`, or if it is implicitly a + /// static method. + pub(crate) fn is_staticmethod(self, db: &'db dyn Db) -> bool { + self.has_known_decorator(db, FunctionDecorators::STATICMETHOD) || self.name(db) == "__new__" + } + /// If the implementation of this function is deprecated, returns the `@warnings.deprecated`. /// /// Checking if an overload is deprecated requires deeper call analysis.