mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 22:31:47 +00:00
[ty] Ensure that a function-literal type is always equivalent to itself (#18227)
This commit is contained in:
parent
60b486abce
commit
e8d4f6d891
3 changed files with 38 additions and 10 deletions
|
@ -334,4 +334,30 @@ static_assert(is_equivalent_to(CallableTypeOf[pg], CallableTypeOf[cpg]))
|
||||||
static_assert(is_equivalent_to(CallableTypeOf[cpg], CallableTypeOf[pg]))
|
static_assert(is_equivalent_to(CallableTypeOf[cpg], CallableTypeOf[pg]))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Function-literal types and bound-method types
|
||||||
|
|
||||||
|
Function-literal types and bound-method types are always considered self-equivalent, even if they
|
||||||
|
have unannotated parameters, or parameters with not-fully-static annotations.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[environment]
|
||||||
|
python-version = "3.12"
|
||||||
|
```
|
||||||
|
|
||||||
|
```py
|
||||||
|
from ty_extensions import is_equivalent_to, TypeOf, static_assert
|
||||||
|
|
||||||
|
def f(): ...
|
||||||
|
|
||||||
|
static_assert(is_equivalent_to(TypeOf[f], TypeOf[f]))
|
||||||
|
|
||||||
|
class A:
|
||||||
|
def method(self) -> int:
|
||||||
|
return 42
|
||||||
|
|
||||||
|
static_assert(is_equivalent_to(TypeOf[A.method], TypeOf[A.method]))
|
||||||
|
type X = TypeOf[A.method]
|
||||||
|
static_assert(is_equivalent_to(X, X))
|
||||||
|
```
|
||||||
|
|
||||||
[the equivalence relation]: https://typing.python.org/en/latest/spec/glossary.html#term-equivalent
|
[the equivalence relation]: https://typing.python.org/en/latest/spec/glossary.html#term-equivalent
|
||||||
|
|
|
@ -7146,10 +7146,11 @@ impl<'db> FunctionType<'db> {
|
||||||
// However, our representation of a function literal includes any specialization that
|
// However, our representation of a function literal includes any specialization that
|
||||||
// should be applied to the signature. Different specializations of the same function
|
// should be applied to the signature. Different specializations of the same function
|
||||||
// literal are only subtypes of each other if they result in subtype signatures.
|
// literal are only subtypes of each other if they result in subtype signatures.
|
||||||
self.body_scope(db) == other.body_scope(db)
|
self.normalized(db) == other.normalized(db)
|
||||||
&& self
|
|| (self.body_scope(db) == other.body_scope(db)
|
||||||
.into_callable_type(db)
|
&& self
|
||||||
.is_subtype_of(db, other.into_callable_type(db))
|
.into_callable_type(db)
|
||||||
|
.is_subtype_of(db, other.into_callable_type(db)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_assignable_to(self, db: &'db dyn Db, other: Self) -> bool {
|
fn is_assignable_to(self, db: &'db dyn Db, other: Self) -> bool {
|
||||||
|
@ -7164,10 +7165,11 @@ impl<'db> FunctionType<'db> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_equivalent_to(self, db: &'db dyn Db, other: Self) -> bool {
|
fn is_equivalent_to(self, db: &'db dyn Db, other: Self) -> bool {
|
||||||
self.body_scope(db) == other.body_scope(db)
|
self.normalized(db) == other.normalized(db)
|
||||||
&& self
|
|| (self.body_scope(db) == other.body_scope(db)
|
||||||
.into_callable_type(db)
|
&& self
|
||||||
.is_equivalent_to(db, other.into_callable_type(db))
|
.into_callable_type(db)
|
||||||
|
.is_equivalent_to(db, other.into_callable_type(db)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_gradual_equivalent_to(self, db: &'db dyn Db, other: Self) -> bool {
|
fn is_gradual_equivalent_to(self, db: &'db dyn Db, other: Self) -> bool {
|
||||||
|
|
|
@ -302,8 +302,8 @@ impl<'db> Signature<'db> {
|
||||||
|
|
||||||
pub(crate) fn normalized(&self, db: &'db dyn Db) -> Self {
|
pub(crate) fn normalized(&self, db: &'db dyn Db) -> Self {
|
||||||
Self {
|
Self {
|
||||||
generic_context: self.generic_context,
|
generic_context: self.generic_context.map(|ctx| ctx.normalized(db)),
|
||||||
inherited_generic_context: self.inherited_generic_context,
|
inherited_generic_context: self.inherited_generic_context.map(|ctx| ctx.normalized(db)),
|
||||||
parameters: self
|
parameters: self
|
||||||
.parameters
|
.parameters
|
||||||
.iter()
|
.iter()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue