mirror of https://github.com/astral-sh/ruff
[ty] Allow `tuple[Any, ...]` to assign to `tuple[int, *tuple[int, ...]]` (#21803)
## Summary Closes https://github.com/astral-sh/ty/issues/1750.
This commit is contained in:
parent
9714c589e1
commit
ef45c97dab
|
|
@ -537,6 +537,9 @@ static_assert(is_assignable_to(tuple[Any, ...], tuple[Any, Any]))
|
|||
static_assert(is_assignable_to(tuple[Any, ...], tuple[int, ...]))
|
||||
static_assert(is_assignable_to(tuple[Any, ...], tuple[int]))
|
||||
static_assert(is_assignable_to(tuple[Any, ...], tuple[int, int]))
|
||||
static_assert(is_assignable_to(tuple[Any, ...], tuple[int, *tuple[int, ...]]))
|
||||
static_assert(is_assignable_to(tuple[Any, ...], tuple[*tuple[int, ...], int]))
|
||||
static_assert(is_assignable_to(tuple[Any, ...], tuple[int, *tuple[int, ...], int]))
|
||||
```
|
||||
|
||||
This also applies when `tuple[Any, ...]` is unpacked into a mixed tuple.
|
||||
|
|
@ -560,6 +563,10 @@ static_assert(is_assignable_to(tuple[*tuple[Any, ...], int], tuple[int, ...]))
|
|||
static_assert(is_assignable_to(tuple[*tuple[Any, ...], int], tuple[int]))
|
||||
static_assert(is_assignable_to(tuple[*tuple[Any, ...], int], tuple[int, int]))
|
||||
|
||||
# `*tuple[Any, ...]` can materialize to a tuple of any length as a special case,
|
||||
# so this passes:
|
||||
static_assert(is_assignable_to(tuple[*tuple[Any, ...], Any], tuple[*tuple[Any, ...], Any, Any]))
|
||||
|
||||
static_assert(is_assignable_to(tuple[int, *tuple[Any, ...], int], tuple[int, *tuple[Any, ...], int]))
|
||||
static_assert(is_assignable_to(tuple[int, *tuple[Any, ...], int], tuple[Any, ...]))
|
||||
static_assert(not is_assignable_to(tuple[int, *tuple[Any, ...], int], tuple[Any]))
|
||||
|
|
@ -580,6 +587,9 @@ static_assert(not is_assignable_to(tuple[int, ...], tuple[Any, Any]))
|
|||
static_assert(is_assignable_to(tuple[int, ...], tuple[int, ...]))
|
||||
static_assert(not is_assignable_to(tuple[int, ...], tuple[int]))
|
||||
static_assert(not is_assignable_to(tuple[int, ...], tuple[int, int]))
|
||||
static_assert(not is_assignable_to(tuple[int, ...], tuple[int, *tuple[int, ...]]))
|
||||
static_assert(not is_assignable_to(tuple[int, ...], tuple[*tuple[int, ...], int]))
|
||||
static_assert(not is_assignable_to(tuple[int, ...], tuple[int, *tuple[int, ...], int]))
|
||||
|
||||
static_assert(is_assignable_to(tuple[int, *tuple[int, ...]], tuple[int, *tuple[Any, ...]]))
|
||||
static_assert(is_assignable_to(tuple[int, *tuple[int, ...]], tuple[Any, ...]))
|
||||
|
|
|
|||
|
|
@ -998,11 +998,23 @@ impl<'db> VariableLengthTuple<Type<'db>> {
|
|||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
),
|
||||
EitherOrBoth::Right(_) => {
|
||||
EitherOrBoth::Right(other_ty) => {
|
||||
// The rhs has a required element that the lhs is not guaranteed to
|
||||
// provide.
|
||||
// provide, unless the lhs has a dynamic variable-length portion
|
||||
// that can materialize to provide it (for assignability only),
|
||||
// as in `tuple[Any, ...]` matching `tuple[int, int]`.
|
||||
if !relation.is_assignability() || !self.variable.is_dynamic() {
|
||||
return ConstraintSet::from(false);
|
||||
}
|
||||
self.variable.has_relation_to_impl(
|
||||
db,
|
||||
other_ty,
|
||||
inferable,
|
||||
relation,
|
||||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
)
|
||||
}
|
||||
};
|
||||
if result
|
||||
.intersect(db, pair_constraints)
|
||||
|
|
@ -1037,11 +1049,23 @@ impl<'db> VariableLengthTuple<Type<'db>> {
|
|||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
),
|
||||
EitherOrBoth::Right(_) => {
|
||||
EitherOrBoth::Right(other_ty) => {
|
||||
// The rhs has a required element that the lhs is not guaranteed to
|
||||
// provide.
|
||||
// provide, unless the lhs has a dynamic variable-length portion
|
||||
// that can materialize to provide it (for assignability only),
|
||||
// as in `tuple[Any, ...]` matching `tuple[int, int]`.
|
||||
if !relation.is_assignability() || !self.variable.is_dynamic() {
|
||||
return ConstraintSet::from(false);
|
||||
}
|
||||
self.variable.has_relation_to_impl(
|
||||
db,
|
||||
*other_ty,
|
||||
inferable,
|
||||
relation,
|
||||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
)
|
||||
}
|
||||
};
|
||||
if result
|
||||
.intersect(db, pair_constraints)
|
||||
|
|
|
|||
Loading…
Reference in New Issue