Skip to content

Commit

Permalink
Changed handling of tuple[Any, ...] so it is treated as though it's…
Browse files Browse the repository at this point in the history
… bidirectionally type compatible with all tuples regardless of length. This addresses #7053. (#7054)
  • Loading branch information
erictraut authored Jan 20, 2024
1 parent 9ec6beb commit f10455e
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 6 deletions.
12 changes: 11 additions & 1 deletion packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22089,10 +22089,16 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
const destUnboundedOrVariadicIndex = destTypeArgs.findIndex((t) => t.isUnbounded || isVariadicTypeVar(t.type));
const srcUnboundedIndex = srcTypeArgs.findIndex((t) => t.isUnbounded);
const srcVariadicIndex = srcTypeArgs.findIndex((t) => isVariadicTypeVar(t.type));
let isSrcVariadicAny = false;

// If the src contains an unbounded type but the dest does not, it's incompatible.
if (srcUnboundedIndex >= 0 && destUnboundedOrVariadicIndex < 0) {
return false;
// Unless the source contains an [Any, ...].
if (isAnyOrUnknown(srcTypeArgs[srcUnboundedIndex].type)) {
isSrcVariadicAny = true;
} else {
return false;
}
}

if (srcUnboundedIndex >= 0) {
Expand All @@ -22103,6 +22109,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
while (srcTypeArgs.length < destTypeArgs.length) {
srcTypeArgs.splice(srcUnboundedIndex, 0, { type: typeToReplicate, isUnbounded: true });
}

if (isSrcVariadicAny && srcTypeArgs.length > destTypeArgs.length) {
srcTypeArgs.splice(srcUnboundedIndex, 1);
}
}

// Remove any optional parameters from the end of the two lists until the lengths match.
Expand Down
19 changes: 18 additions & 1 deletion packages/pyright-internal/src/tests/samples/tuple1.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This sample file tests various aspects of type analysis for tuples.

import os
from typing import Callable
from typing import Any, Callable
from typing_extensions import TypeVarTuple, Unpack

Ts = TypeVarTuple("Ts")
Expand Down Expand Up @@ -226,3 +226,20 @@ def func17(var: tuple[int, ...]) -> str:
f1 = func16

f1 = func17


def func18(a: tuple[int, *tuple[Any, ...], str], b: tuple[Any, ...]):
a1: tuple[int, str] = a
a2: tuple[int, int, str] = a
a3: tuple[int, int, str, str] = a
a4: tuple[int, *tuple[int, ...], str] = a

# This should generate an error.
a5: tuple[str, int, str, str] = a

# This should generate an error.
a6: tuple[int, int, str, int] = a

b1: tuple[()] = b
b2: tuple[int, int, str] = b
b3: tuple[int, *tuple[int, ...], str] = b
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,4 @@ def func4(y: Array[Any, Unpack[tuple[Any, ...]]]):
reveal_type(y, expected_text="Array[Any, *tuple[Any, ...]]")
expect_variadic_array1(y)
expect_variadic_array2(y)

# This should generate an error because of a tuple size mismatch.
expect_precise_array(y)
2 changes: 1 addition & 1 deletion packages/pyright-internal/src/tests/typeEvaluator1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ test('Optional2', () => {
test('Tuple1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['tuple1.py']);

TestUtils.validateResults(analysisResults, 15);
TestUtils.validateResults(analysisResults, 17);
});

test('Tuple2', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/pyright-internal/src/tests/typeEvaluator3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,7 @@ test('VariadicTypeVar10', () => {

configOptions.defaultPythonVersion = PythonVersion.V3_11;
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['variadicTypeVar10.py'], configOptions);
TestUtils.validateResults(analysisResults, 3);
TestUtils.validateResults(analysisResults, 2);
});

test('VariadicTypeVar11', () => {
Expand Down

0 comments on commit f10455e

Please sign in to comment.