mirror of
https://github.com/astral-sh/ruff
synced 2026-01-21 05:20:49 -05:00
[ty] Infer implicit type of cls in __new__ methods (#22584)
## Summary Resolves https://github.com/astral-sh/ty/issues/2489.
This commit is contained in:
@@ -585,8 +585,8 @@ class Baz(Bar[Self]): ...
|
||||
|
||||
class MyMetaclass(type):
|
||||
# TODO: reject the Self usage. because self cannot be used within a metaclass.
|
||||
def __new__(cls) -> Self:
|
||||
return super().__new__(cls)
|
||||
def __new__(cls, name, bases, dct) -> Self:
|
||||
return cls(name, bases, dct)
|
||||
```
|
||||
|
||||
## Explicit annotations override implicit `Self`
|
||||
|
||||
@@ -271,7 +271,7 @@ def f[T](x: T) -> list[T]:
|
||||
|
||||
class A:
|
||||
def __new__(cls, value: list[int | str]):
|
||||
return super().__new__(cls, value)
|
||||
return super().__new__(cls)
|
||||
|
||||
def __init__(self, value: list[int | None]): ...
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ from typing_extensions import Self
|
||||
|
||||
class Base:
|
||||
def __new__(cls, x: int) -> Self:
|
||||
return cls()
|
||||
return cls(x)
|
||||
|
||||
class Foo(Base): ...
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ use crate::types::diagnostic::{
|
||||
use crate::types::enums::is_enum_class_by_inheritance;
|
||||
use crate::types::function::{
|
||||
FunctionDecorators, FunctionLiteral, FunctionType, KnownFunction, OverloadLiteral,
|
||||
is_implicit_classmethod, is_implicit_staticmethod,
|
||||
is_implicit_classmethod,
|
||||
};
|
||||
use crate::types::generics::{
|
||||
GenericContext, InferableTypeVars, LegacyGenericBase, SpecializationBuilder, bind_typevar,
|
||||
@@ -2915,10 +2915,6 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
let function_node = function_definition.node(self.module());
|
||||
let function_name = &function_node.name;
|
||||
|
||||
if is_implicit_staticmethod(function_name) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut is_classmethod = is_implicit_classmethod(function_name);
|
||||
let inference = infer_definition_types(db, method_definition);
|
||||
for decorator in &function_node.decorator_list {
|
||||
@@ -2942,7 +2938,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
.as_class_literal()?;
|
||||
|
||||
let typing_self = typing_self(db, self.scope(), Some(method_definition), class_literal);
|
||||
if is_classmethod {
|
||||
if is_classmethod || function_name == "__new__" {
|
||||
typing_self
|
||||
.map(|typing_self| SubclassOfType::from(db, SubclassOfInner::TypeVar(typing_self)))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user