[red-knot] Special case @final, @override (#17608)

## Summary

This PR adds special-casing for `@final` and `@override` decorator for a
similar reason as https://github.com/astral-sh/ruff/pull/17591 to
support the invalid overload check.

Both `final` and `override` are identity functions which can be removed
once `TypeVar` support is added.
This commit is contained in:
Dhruv Manilawala 2025-04-25 03:15:23 +05:30 committed by GitHub
parent ef0343189c
commit f1a539dac6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 33 additions and 1 deletions

View file

@ -1,3 +1,4 @@
Expression # cycle panic (signature_)
Tanjun # cycle panic (signature_)
aiohttp # missing expression ID
alerta # missing expression ID

View file

@ -1,5 +1,4 @@
AutoSplit
Expression
PyGithub
PyWinCtl
SinbadCogs

View file

@ -6027,6 +6027,10 @@ bitflags! {
const OVERLOAD = 1 << 2;
/// `@abc.abstractmethod`
const ABSTRACT_METHOD = 1 << 3;
/// `@typing.final`
const FINAL = 1 << 4;
/// `@typing.override`
const OVERRIDE = 1 << 6;
}
}
@ -6400,6 +6404,8 @@ pub enum KnownFunction {
Cast,
/// `typing(_extensions).overload`
Overload,
/// `typing(_extensions).override`
Override,
/// `typing(_extensions).is_protocol`
IsProtocol,
/// `typing(_extensions).get_protocol_members`
@ -6467,6 +6473,7 @@ impl KnownFunction {
| Self::AssertNever
| Self::Cast
| Self::Overload
| Self::Override
| Self::RevealType
| Self::Final
| Self::IsProtocol
@ -7844,6 +7851,7 @@ pub(crate) mod tests {
KnownFunction::Cast
| KnownFunction::Final
| KnownFunction::Overload
| KnownFunction::Override
| KnownFunction::RevealType
| KnownFunction::AssertType
| KnownFunction::AssertNever

View file

@ -584,6 +584,14 @@ impl<'db> Bindings<'db> {
}
}
Some(KnownFunction::Override) => {
// TODO: This can be removed once we understand legacy generics because the
// typeshed definition for `typing.overload` is an identity function.
if let [Some(ty)] = overload.parameter_types() {
overload.set_return_type(*ty);
}
}
Some(KnownFunction::AbstractMethod) => {
// TODO: This can be removed once we understand legacy generics because the
// typeshed definition for `abc.abstractmethod` is an identity function.
@ -592,6 +600,14 @@ impl<'db> Bindings<'db> {
}
}
Some(KnownFunction::Final) => {
// TODO: This can be removed once we understand legacy generics because the
// typeshed definition for `abc.abstractmethod` is an identity function.
if let [Some(ty)] = overload.parameter_types() {
overload.set_return_type(*ty);
}
}
Some(KnownFunction::GetattrStatic) => {
let [Some(instance_ty), Some(attr_name), default] =
overload.parameter_types()

View file

@ -1500,6 +1500,14 @@ impl<'db> TypeInferenceBuilder<'db> {
function_decorators |= FunctionDecorators::ABSTRACT_METHOD;
continue;
}
Some(KnownFunction::Final) => {
function_decorators |= FunctionDecorators::FINAL;
continue;
}
Some(KnownFunction::Override) => {
function_decorators |= FunctionDecorators::OVERRIDE;
continue;
}
_ => {}
}
}