mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 22:54:42 +00:00
parent
caf3c916e8
commit
1297d6a9eb
3 changed files with 19 additions and 2 deletions
|
@ -4247,6 +4247,13 @@ impl<'db> Type<'db> {
|
||||||
Some(KnownClass::Tuple) => {
|
Some(KnownClass::Tuple) => {
|
||||||
let object = Type::object(db);
|
let object = Type::object(db);
|
||||||
|
|
||||||
|
// ```py
|
||||||
|
// class tuple:
|
||||||
|
// @overload
|
||||||
|
// def __new__(cls) -> tuple[()]: ...
|
||||||
|
// @overload
|
||||||
|
// def __new__(cls, iterable: Iterable[object]) -> tuple[object, ...]: ...
|
||||||
|
// ```
|
||||||
CallableBinding::from_overloads(
|
CallableBinding::from_overloads(
|
||||||
self,
|
self,
|
||||||
[
|
[
|
||||||
|
@ -4308,6 +4315,13 @@ impl<'db> Type<'db> {
|
||||||
let instantiated = Type::instance(db, ClassType::from(alias));
|
let instantiated = Type::instance(db, ClassType::from(alias));
|
||||||
|
|
||||||
let parameters = if alias.origin(db).is_known(db, KnownClass::Tuple) {
|
let parameters = if alias.origin(db).is_known(db, KnownClass::Tuple) {
|
||||||
|
// ```py
|
||||||
|
// class tuple:
|
||||||
|
// @overload
|
||||||
|
// def __new__(cls: type[tuple[()]], iterable: tuple[()] = ()) -> tuple[()]: ...
|
||||||
|
// @overload
|
||||||
|
// def __new__[T](cls: type[tuple[T, ...]], iterable: tuple[T, ...]) -> tuple[T, ...]: ...
|
||||||
|
// ```
|
||||||
let spec = alias.specialization(db).tuple(db);
|
let spec = alias.specialization(db).tuple(db);
|
||||||
let mut parameter =
|
let mut parameter =
|
||||||
Parameter::positional_only(Some(Name::new_static("iterable")))
|
Parameter::positional_only(Some(Name::new_static("iterable")))
|
||||||
|
|
|
@ -973,13 +973,16 @@ impl<'db> Bindings<'db> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(KnownClass::Tuple) if overload_index == 1 => {
|
Some(KnownClass::Tuple) if overload_index == 1 => {
|
||||||
|
// `tuple(range(42))` => `tuple[int, ...]`
|
||||||
|
// BUT `tuple((1, 2))` => `tuple[Literal[1], Literal[2]]` rather than `tuple[Literal[1, 2], ...]`
|
||||||
if let [Some(argument)] = overload.parameter_types() {
|
if let [Some(argument)] = overload.parameter_types() {
|
||||||
let overridden_return =
|
let overridden_return =
|
||||||
argument.into_tuple().map(Type::Tuple).unwrap_or_else(|| {
|
argument.into_tuple().map(Type::Tuple).unwrap_or_else(|| {
|
||||||
// Some awkward special handling is required here because of the fact
|
// Some awkward special handling is required here because of the fact
|
||||||
// that calling `try_iterate()` on `Never` returns `Never`,
|
// that calling `try_iterate()` on `Never` returns `Never`,
|
||||||
// but `tuple[Never, ...]` eagerly simplifies to `tuple[()]`,
|
// but `tuple[Never, ...]` eagerly simplifies to `tuple[()]`,
|
||||||
// which will cause us to emit false positives if we index into the tuple
|
// which will cause us to emit false positives if we index into the tuple.
|
||||||
|
// Using `tuple[Unknown, ...]` avoids these false positives.
|
||||||
let specialization = if argument.is_never() {
|
let specialization = if argument.is_never() {
|
||||||
Type::unknown()
|
Type::unknown()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2427,7 +2427,7 @@ impl KnownClass {
|
||||||
| Self::Float
|
| Self::Float
|
||||||
| Self::Enum
|
| Self::Enum
|
||||||
| Self::ABCMeta
|
| Self::ABCMeta
|
||||||
| KnownClass::Iterable
|
| Self::Iterable
|
||||||
// Empty tuples are AlwaysFalse; non-empty tuples are AlwaysTrue
|
// Empty tuples are AlwaysFalse; non-empty tuples are AlwaysTrue
|
||||||
| Self::NamedTuple
|
| Self::NamedTuple
|
||||||
// Evaluating `NotImplementedType` in a boolean context was deprecated in Python 3.9
|
// Evaluating `NotImplementedType` in a boolean context was deprecated in Python 3.9
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue