mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 18:28:56 +00:00
[red-knot] Check if callable type is fully static (#16633)
## Summary Part of #15382 This PR adds the check for whether a callable type is fully static or not. A callable type is fully static if all of the parameter types are fully static _and_ the return type is fully static _and_ if it does not use the gradual form (`...`) for its parameters. ## Test Plan Update `is_fully_static.md` with callable types. It seems that currently this test is grouped into either fully static or not, I think it would be useful to split them up in groups like callable, etc. I intentionally avoided that in this PR but I'll put up a PR for an appropriate split. Note: I've an explicit goal of updating the property tests with the new callable types once all relations are implemented.
This commit is contained in:
parent
6b84253679
commit
6de2b2873b
2 changed files with 50 additions and 7 deletions
|
@ -5,7 +5,7 @@ A type is fully static iff it does not contain any gradual forms.
|
|||
## Fully-static
|
||||
|
||||
```py
|
||||
from typing_extensions import Literal, LiteralString, Never
|
||||
from typing_extensions import Literal, LiteralString, Never, Callable
|
||||
from knot_extensions import Intersection, Not, TypeOf, is_fully_static, static_assert
|
||||
|
||||
static_assert(is_fully_static(Never))
|
||||
|
@ -38,7 +38,7 @@ static_assert(is_fully_static(type[object]))
|
|||
## Non-fully-static
|
||||
|
||||
```py
|
||||
from typing_extensions import Any, Literal, LiteralString
|
||||
from typing_extensions import Any, Literal, LiteralString, Callable
|
||||
from knot_extensions import Intersection, Not, TypeOf, Unknown, is_fully_static, static_assert
|
||||
|
||||
static_assert(not is_fully_static(Any))
|
||||
|
@ -52,3 +52,26 @@ static_assert(not is_fully_static(tuple[Any, ...]))
|
|||
static_assert(not is_fully_static(tuple[int, Any]))
|
||||
static_assert(not is_fully_static(type[Any]))
|
||||
```
|
||||
|
||||
## Callable
|
||||
|
||||
```py
|
||||
from typing_extensions import Callable, Any
|
||||
from knot_extensions import Unknown, is_fully_static, static_assert
|
||||
|
||||
static_assert(is_fully_static(Callable[[], int]))
|
||||
static_assert(is_fully_static(Callable[[int, str], int]))
|
||||
|
||||
static_assert(not is_fully_static(Callable[..., int]))
|
||||
static_assert(not is_fully_static(Callable[[], Any]))
|
||||
static_assert(not is_fully_static(Callable[[int, Unknown], int]))
|
||||
```
|
||||
|
||||
The invalid forms of `Callable` annotation are never fully static because we represent them with the
|
||||
`(...) -> Unknown` signature.
|
||||
|
||||
```py
|
||||
static_assert(not is_fully_static(Callable))
|
||||
# error: [invalid-type-form]
|
||||
static_assert(not is_fully_static(Callable[int, int]))
|
||||
```
|
||||
|
|
|
@ -1331,11 +1331,7 @@ impl<'db> Type<'db> {
|
|||
.elements(db)
|
||||
.iter()
|
||||
.all(|elem| elem.is_fully_static(db)),
|
||||
Type::Callable(CallableType::General(_)) => {
|
||||
// TODO: `Callable` is not fully static when the parameter argument is `...` or
|
||||
// when any parameter type or return type is not fully static.
|
||||
false
|
||||
}
|
||||
Type::Callable(CallableType::General(callable)) => callable.is_fully_static(db),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4518,6 +4514,30 @@ impl<'db> GeneralCallableType<'db> {
|
|||
Signature::new(Parameters::unknown(), Some(Type::unknown())),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is a fully static callable type.
|
||||
///
|
||||
/// A callable type is fully static if all of its parameters and return type are fully static
|
||||
/// and if it does not use gradual form (`...`) for its parameters.
|
||||
pub(crate) fn is_fully_static(self, db: &'db dyn Db) -> bool {
|
||||
let signature = self.signature(db);
|
||||
|
||||
if signature.parameters().is_gradual() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if signature.parameters().iter().any(|parameter| {
|
||||
parameter
|
||||
.annotated_type()
|
||||
.is_some_and(|annotated_type| !annotated_type.is_fully_static(db))
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
|
||||
signature
|
||||
.return_ty
|
||||
.is_some_and(|return_type| return_type.is_fully_static(db))
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that represents callable objects.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue