Skip to content

Commit 0995c1c

Browse files
committed
[ty] Followups to tuple constructor improvements in #18987
1 parent c60e590 commit 0995c1c

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

crates/ty_python_semantic/src/types.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4247,6 +4247,13 @@ impl<'db> Type<'db> {
42474247
Some(KnownClass::Tuple) => {
42484248
let object = Type::object(db);
42494249

4250+
// ```py
4251+
// class tuple:
4252+
// @overload
4253+
// def __new__(cls) -> tuple[()]: ...
4254+
// @overload
4255+
// def __new__(cls, iterable: Iterable[object]) -> tuple[object, ...]: ...
4256+
// ```
42504257
CallableBinding::from_overloads(
42514258
self,
42524259
[
@@ -4308,6 +4315,13 @@ impl<'db> Type<'db> {
43084315
let instantiated = Type::instance(db, ClassType::from(alias));
43094316

43104317
let parameters = if alias.origin(db).is_known(db, KnownClass::Tuple) {
4318+
// ```py
4319+
// class tuple:
4320+
// @overload
4321+
// def __new__(cls: type[tuple[()]], iterable: tuple[()] = ()) -> tuple[()]: ...
4322+
// @overload
4323+
// def __new__[T](cls: type[tuple[T, ...]], iterable: tuple[T, ...]) -> tuple[T, ...]: ...
4324+
// ```
43114325
let spec = alias.specialization(db).tuple(db);
43124326
let mut parameter =
43134327
Parameter::positional_only(Some(Name::new_static("iterable")))

crates/ty_python_semantic/src/types/call/bind.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,13 +973,16 @@ impl<'db> Bindings<'db> {
973973
}
974974

975975
Some(KnownClass::Tuple) if overload_index == 1 => {
976+
// `tuple(range(42))` => `tuple[int, ...]`
977+
// BUT `tuple((1, 2))` => `tuple[Literal[1], Literal[2]]` rather than `tuple[Literal[1, 2], ...]`
976978
if let [Some(argument)] = overload.parameter_types() {
977979
let overridden_return =
978980
argument.into_tuple().map(Type::Tuple).unwrap_or_else(|| {
979981
// Some awkward special handling is required here because of the fact
980982
// that calling `try_iterate()` on `Never` returns `Never`,
981983
// but `tuple[Never, ...]` eagerly simplifies to `tuple[()]`,
982-
// which will cause us to emit false positives if we index into the tuple
984+
// which will cause us to emit false positives if we index into the tuple.
985+
// Using `tuple[Unknown, ...]` avoids these false positives.
983986
let specialization = if argument.is_never() {
984987
Type::unknown()
985988
} else {

crates/ty_python_semantic/src/types/class.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2427,7 +2427,7 @@ impl KnownClass {
24272427
| Self::Float
24282428
| Self::Enum
24292429
| Self::ABCMeta
2430-
| KnownClass::Iterable
2430+
| Self::Iterable
24312431
// Empty tuples are AlwaysFalse; non-empty tuples are AlwaysTrue
24322432
| Self::NamedTuple
24332433
// Evaluating `NotImplementedType` in a boolean context was deprecated in Python 3.9

0 commit comments

Comments
 (0)