diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/callable.md b/crates/ty_python_semantic/resources/mdtest/annotations/callable.md index 728566d30e..34dd6e7d5d 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/callable.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/callable.md @@ -407,4 +407,22 @@ def f_okay(c: Callable[[], None]): c.__qualname__ = "my_callable" # okay ``` +## From a class + +### Subclasses should return themselves, not superclass + +```py +from ty_extensions import into_callable + +class Base: + def __init__(self) -> None: + pass + +class A(Base): + pass + +# revealed: () -> A +reveal_type(into_callable(A)) +``` + [gradual form]: https://typing.python.org/en/latest/spec/glossary.html#term-gradual-form diff --git a/crates/ty_python_semantic/src/types/class.rs b/crates/ty_python_semantic/src/types/class.rs index d5fd42ace7..a503421713 100644 --- a/crates/ty_python_semantic/src/types/class.rs +++ b/crates/ty_python_semantic/src/types/class.rs @@ -1257,6 +1257,7 @@ impl<'db> ClassType<'db> { let self_annotation = signature .parameters() .get_positional(0) + .filter(|parameter| !parameter.inferred_annotation) .and_then(Parameter::annotated_type) .filter(|ty| { ty.as_typevar() diff --git a/crates/ty_python_semantic/src/types/signatures.rs b/crates/ty_python_semantic/src/types/signatures.rs index 0a70337930..33266f8dde 100644 --- a/crates/ty_python_semantic/src/types/signatures.rs +++ b/crates/ty_python_semantic/src/types/signatures.rs @@ -2167,7 +2167,7 @@ pub(crate) struct Parameter<'db> { /// Does the type of this parameter come from an explicit annotation, or was it inferred from /// the context, like `Self` for the `self` parameter of instance methods. - inferred_annotation: bool, + pub(crate) inferred_annotation: bool, kind: ParameterKind<'db>, pub(crate) form: ParameterForm,