Skip to content

Commit

Permalink
Fixed bug in tuple type compatibility logic that resulted in a false …
Browse files Browse the repository at this point in the history
…negative when dest type includes an upacked unbounded tuple plus additional entries. This addresses microsoft#7115. (microsoft#7152)

Fixed bug in tuple type compatibility logic that resulted in a false positive when dest type is `tuple[Any, ...]`. This addresses microsoft#7129.
Improved error messages for tuple type mismatches that involve tuples with indeterminate types.
  • Loading branch information
erictraut committed Jan 28, 2024
1 parent 725f91f commit 1d4b1cc
Show file tree
Hide file tree
Showing 19 changed files with 274 additions and 303 deletions.
508 changes: 223 additions & 285 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions packages/pyright-internal/src/localization/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1422,12 +1422,20 @@ export namespace Localizer {
new ParameterizedString<{ entry: number }>(getRawString('DiagnosticAddendum.tupleEntryTypeMismatch'));
export const tupleAssignmentMismatch = () =>
new ParameterizedString<{ type: string }>(getRawString('DiagnosticAddendum.tupleAssignmentMismatch'));
export const tupleSizeIndeterminate = () =>
new ParameterizedString<{ expected: number }>(getRawString('DiagnosticAddendum.tupleSizeIndeterminate'));
export const tupleSizeIndeterminateSrc = () =>
new ParameterizedString<{ expected: number }>(getRawString('DiagnosticAddendum.tupleSizeIndeterminateSrc'));
export const tupleSizeIndeterminateSrcDest = () =>
new ParameterizedString<{ expected: number }>(
getRawString('DiagnosticAddendum.tupleSizeIndeterminateSrcDest')
);
export const tupleSizeMismatch = () =>
new ParameterizedString<{ expected: number; received: number }>(
getRawString('DiagnosticAddendum.tupleSizeMismatch')
);
export const tupleSizeMismatchIndeterminateDest = () =>
new ParameterizedString<{ expected: number; received: number }>(
getRawString('DiagnosticAddendum.tupleSizeMismatchIndeterminateDest')
);
export const typeAliasInstanceCheck = () => getRawString('DiagnosticAddendum.typeAliasInstanceCheck');
export const typeAssignmentMismatch = () =>
new ParameterizedString<{ sourceType: string; destType: string }>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Zobrazit deklaraci proměnné",
"tupleAssignmentMismatch": "Typ „{type}“ není kompatibilní s cílovou řazenou kolekcí členů",
"tupleEntryTypeMismatch": "Položka řazené kolekce členů {entry} je nesprávného typu",
"tupleSizeIndeterminate": "Neshoda velikosti řazené kolekce členů; Očekávalo se {expected}, ale přijalo se neurčité.",
"tupleSizeIndeterminateSrc": "Neshoda velikosti řazené kolekce členů; Očekávalo se {expected}, ale přijalo se neurčité.",
"tupleSizeMismatch": "Neshoda velikosti řazené kolekce členů; Očekávalo se {expected}, ale přijalo se {received}.",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "Typ {sourceType} se nedá přiřadit k typu {destType}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Siehe Variablendeklaration",
"tupleAssignmentMismatch": "Der Typ \"{type}\" ist nicht mit dem Zieltupel kompatibel.",
"tupleEntryTypeMismatch": "Der Tupeleintrag {entry} ist ein falscher Typ.",
"tupleSizeIndeterminate": "Nicht übereinstimmende Tupelgröße; {expected} erwartet, aber unbestimmt empfangen",
"tupleSizeIndeterminateSrc": "Nicht übereinstimmende Tupelgröße; {expected} erwartet, aber unbestimmt empfangen",
"tupleSizeMismatch": "Nicht übereinstimmende Tupelgröße; {expected} erwartet, aber {received} empfangen",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "Der Typ \"{sourceType}\" kann dem Typ \"{destType}\" nicht zugewiesen werden.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,10 @@
"seeVariableDeclaration": "See variable declaration",
"tupleEntryTypeMismatch": "Tuple entry {entry} is incorrect type",
"tupleAssignmentMismatch": "Type \"{type}\" is incompatible with target tuple",
"tupleSizeIndeterminate": "Tuple size mismatch; expected {expected} but received indeterminate",
"tupleSizeIndeterminateSrc": "Tuple size mismatch; expected {expected} but received indeterminate",
"tupleSizeIndeterminateSrcDest": "Tuple size mismatch; expected {expected} or more but received indeterminate",
"tupleSizeMismatch": "Tuple size mismatch; expected {expected} but received {received}",
"tupleSizeMismatchIndeterminateDest": "Tuple size mismatch; expected {expected} or more but received {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "Type \"{sourceType}\" cannot be assigned to type \"{destType}\"",
"typeBound": "Type \"{sourceType}\" is incompatible with bound type \"{destType}\" for type variable \"{name}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "declaración de variable out",
"tupleAssignmentMismatch": "El tipo \"{type}\" no es compatible con la tupla de destino",
"tupleEntryTypeMismatch": "La entrada {entry} de la tupla es de tipo incorrecto",
"tupleSizeIndeterminate": "El tamaño de la tupla no coincide; se esperaba {expected} pero se recibió uno indeterminado",
"tupleSizeIndeterminateSrc": "El tamaño de la tupla no coincide; se esperaba {expected} pero se recibió uno indeterminado",
"tupleSizeMismatch": "El tamaño de la tupla no coincide; se esperaba {expected} pero se recibió {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "El tipo \"{sourceType}\" no puede asignarse al tipo \"{destType}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Voir déclaration de variable",
"tupleAssignmentMismatch": "Le type \"{type}\" est incompatible avec le tuple cible",
"tupleEntryTypeMismatch": "Le type de l’entrée de tuple {entry} est incorrect",
"tupleSizeIndeterminate": "Incompatibilité de taille de tuple ; attendu {expected} mais reçu pour une durée indéterminée",
"tupleSizeIndeterminateSrc": "Incompatibilité de taille de tuple ; attendu {expected} mais reçu pour une durée indéterminée",
"tupleSizeMismatch": "Incompatibilité de taille de tuple ; attendu {expected} mais reçu {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "Impossible d’affecter le type « {sourceType} » au type « {destType} »",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Vedere la dichiarazione di variabile",
"tupleAssignmentMismatch": "Il tipo \"{type}\" non è compatibile con la tupla di destinazione",
"tupleEntryTypeMismatch": "Il tipo della voce di tupla {entry} non è corretto",
"tupleSizeIndeterminate": "Dimensioni tupla non corrispondenti; previsto {expected} ma ricevuto indeterminato",
"tupleSizeIndeterminateSrc": "Dimensioni tupla non corrispondenti; previsto {expected} ma ricevuto indeterminato",
"tupleSizeMismatch": "Dimensioni tupla non corrispondenti; previsto {expected} ma ricevuto {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "impossibile assegnare il tipo \"{sourceType}\" al tipo \"{destType}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "変数宣言を参照してください",
"tupleAssignmentMismatch": "型 \"{type}\" はターゲット タプルと互換性がありません",
"tupleEntryTypeMismatch": "タプル エントリ {entry} の型が正しくありません",
"tupleSizeIndeterminate": "タプル サイズが一致しません。{expected} が必要ですが、受け取りは不確定です",
"tupleSizeIndeterminateSrc": "タプル サイズが一致しません。{expected} が必要ですが、受け取りは不確定です",
"tupleSizeMismatch": "タプルのサイズが一致しません。{expected} が必要ですが、{received} を受信しました",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "型 \"{sourceType}\" を型 \"{destType}\" に割り当てることはできません",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "변수 선언 보기",
"tupleAssignmentMismatch": "‘{type}’ 형식이 대상 튜플과 호환되지 않습니다.",
"tupleEntryTypeMismatch": "튜플 항목 {entry}이(가) 잘못된 형식입니다.",
"tupleSizeIndeterminate": "튜플 크기 불일치: {expected}이(가) 필요하지만 미정을 받았습니다.",
"tupleSizeIndeterminateSrc": "튜플 크기 불일치: {expected}이(가) 필요하지만 미정을 받았습니다.",
"tupleSizeMismatch": "튜플 크기 불일치: {expected}이(가) 필요하지만 {received}을(를) 받았습니다.",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "\"{sourceType}\" 형식은 \"{destType}\" 형식에 할당할 수 없습니다.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Zobacz deklarację zmiennej",
"tupleAssignmentMismatch": "Typ „{type}” jest niezgodny z docelową krotką",
"tupleEntryTypeMismatch": "Wpis krotki {entry} jest nieprawidłowego typu",
"tupleSizeIndeterminate": "Niezgodność rozmiaru krotki; oczekiwano {expected}, ale otrzymano nieokreślony",
"tupleSizeIndeterminateSrc": "Niezgodność rozmiaru krotki; oczekiwano {expected}, ale otrzymano nieokreślony",
"tupleSizeMismatch": "Niezgodność rozmiaru krotki; oczekiwano {expected}, ale otrzymano {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "Nie można przypisać typu „{sourceType}” do typu „{destType}”",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Consulte a declaração de variável",
"tupleAssignmentMismatch": "O tipo \"{type}\" é incompatível com a tupla de destino",
"tupleEntryTypeMismatch": "A entrada de tupla {entry} é do tipo incorreto",
"tupleSizeIndeterminate": "Incompatibilidade de tamanho de tupla; esperado {expected} mas recebido indeterminado",
"tupleSizeIndeterminateSrc": "Incompatibilidade de tamanho de tupla; esperado {expected} mas recebido indeterminado",
"tupleSizeMismatch": "Incompatibilidade de tamanho de tupla; esperado {expected} mas recebido {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "O tipo \"{sourceType}\" não pode ser atribuído ao tipo \"{destType}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "[M3EiY][นั้§ëë værïæþlë ðëçlærætïøñẤğ倪İЂҰक्र्นั้ढूँ]",
"tupleAssignmentMismatch": "[aLGep][นั้Tÿpë \"{tÿpë}\" ïs ïñçømpætïþlë wïth tærgët tµplëẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]",
"tupleEntryTypeMismatch": "[ny8Sn][นั้Tµplë ëñtrÿ {ëñtrÿ} ïs ïñçørrëçt tÿpëẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]",
"tupleSizeIndeterminate": "[8QDbp][นั้Tµplë sïzë mïsmætçh; ëxpëçtëð {ëxpëçtëð} þµt rëçëïvëð ïñðëtërmïñætëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]",
"tupleSizeIndeterminateSrc": "[8QDbp][นั้Tµplë sïzë mïsmætçh; ëxpëçtëð {ëxpëçtëð} þµt rëçëïvëð ïñðëtërmïñætëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]",
"tupleSizeMismatch": "[F2Yc7][นั้Tµplë sïzë mïsmætçh; ëxpëçtëð {ëxpëçtëð} þµt rëçëïvëð {rëçëïvëð}Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]",
"typeAliasInstanceCheck": "[29G7K][นั้Tÿpë ælïæs çrëætëð wïth \"tÿpë\" stætëmëñt çæññøt þë µsëð wïth ïñstæñçë æñð çlæss çhëçksẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]",
"typeAssignmentMismatch": "[VF9B4][นั้Tÿpë \"{søµrçëTÿpë}\" çæññøt þë æssïgñëð tø tÿpë \"{ðëstTÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Просмотреть объявление переменной",
"tupleAssignmentMismatch": "Тип \"{type}\" несовместим с целевым кортежем",
"tupleEntryTypeMismatch": "Запись кортежа {entry} имеет неверный тип",
"tupleSizeIndeterminate": "Несоответствие размеров кортежа: ожидается \"{expected}\", но получено неопределенное значение",
"tupleSizeIndeterminateSrc": "Несоответствие размеров кортежа: ожидается \"{expected}\", но получено неопределенное значение",
"tupleSizeMismatch": "Несоответствие размеров кортежа: ожидается \"{expected}\", но получено \"{received}\"",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "Тип \"{sourceType}\" нельзя присвоить типу \"{destType}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "Değişken bildirimine bakın",
"tupleAssignmentMismatch": "\"{type}\" türü hedef demet ile uyumsuz",
"tupleEntryTypeMismatch": "{entry} demet girdisi doğru türde değil",
"tupleSizeIndeterminate": "Demet boyutu uyuşmuyor; {expected} bekleniyordu ancak indeterminate alındı",
"tupleSizeIndeterminateSrc": "Demet boyutu uyuşmuyor; {expected} bekleniyordu ancak indeterminate alındı",
"tupleSizeMismatch": "Demet boyutu uyuşmuyor; {expected} bekleniyordu ancak {received} alındı",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "\"{sourceType}\" türü \"{destType}\" türüne atanamaz",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "查看变量声明",
"tupleAssignmentMismatch": "类型\"{type}\"与目标元组不兼容",
"tupleEntryTypeMismatch": "元组条目 {entry} 的类型不正确",
"tupleSizeIndeterminate": "元组大小不匹配;应为 {expected},但收到不确定的",
"tupleSizeIndeterminateSrc": "元组大小不匹配;应为 {expected},但收到不确定的",
"tupleSizeMismatch": "元组大小不匹配;应为 {expected},但收到 {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "无法将类型“{sourceType}”分配给类型“{destType}”",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
"seeVariableDeclaration": "請參閱變數宣告",
"tupleAssignmentMismatch": "型別 \"{type}\" 與目標元組不相容",
"tupleEntryTypeMismatch": "Tuple 項目 {entry} 的類型不正確",
"tupleSizeIndeterminate": "元組大小不符; 預期為 {expected},但收到不確定的大小",
"tupleSizeIndeterminateSrc": "元組大小不符; 預期為 {expected},但收到不確定的大小",
"tupleSizeMismatch": "元組大小不符; 預期為 {expected},但收到 {received}",
"typeAliasInstanceCheck": "Type alias created with \"type\" statement cannot be used with instance and class checks",
"typeAssignmentMismatch": "類型 \"{sourceType}\" 不能指派至類型 \"{destType}\"",
Expand Down
23 changes: 23 additions & 0 deletions packages/pyright-internal/src/tests/samples/tuple1.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,26 @@ def func18(a: tuple[int, *tuple[Any, ...], str], b: tuple[Any, ...]):
b1: tuple[()] = b
b2: tuple[int, int, str] = b
b3: tuple[int, *tuple[int, ...], str] = b


def func19(a: tuple[int, ...], b: tuple[int, *tuple[int, ...]]):
a1: tuple[*tuple[int, ...]] = a

# This should generate an error.
a2: tuple[int, *tuple[int, ...]] = a

# This should generate an error.
a3: tuple[int, *tuple[int, ...], int] = a

# This should generate an error.
a4: tuple[*tuple[int, ...], int] = a

b1: tuple[int, ...] = b
b2: tuple[int, *tuple[int, ...]] = b
b3: tuple[*tuple[int, ...], int] = b

# This should generate an error.
b4: tuple[str, *tuple[int, ...]] = b

# This should generate an error.
b5: tuple[int, int, *tuple[int, ...]] = b
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, 17);
TestUtils.validateResults(analysisResults, 22);
});

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

0 comments on commit 1d4b1cc

Please sign in to comment.