From 0d7d04735f1d62e897e72eee677feed90921cdba Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 28 Oct 2024 08:48:50 -0700 Subject: [PATCH] Fixed a bug that results in a false positive when a class parameterized by a TypeVarTuple is used in conjunction with a Self type. This addresses #9340. --- packages/pyright-internal/src/analyzer/typeUtils.ts | 4 ++++ .../src/tests/samples/typeVarTuple30.py | 11 +++++++++++ .../pyright-internal/src/tests/typeEvaluator6.test.ts | 8 ++++++++ 3 files changed, 23 insertions(+) create mode 100644 packages/pyright-internal/src/tests/samples/typeVarTuple30.py diff --git a/packages/pyright-internal/src/analyzer/typeUtils.ts b/packages/pyright-internal/src/analyzer/typeUtils.ts index 82423da350f1..a6c742d481c5 100644 --- a/packages/pyright-internal/src/analyzer/typeUtils.ts +++ b/packages/pyright-internal/src/analyzer/typeUtils.ts @@ -1156,6 +1156,10 @@ export function selfSpecializeClass(type: ClassType, options?: SelfSpecializeOpt } const typeParams = type.shared.typeParams.map((typeParam) => { + if (isTypeVarTuple(typeParam)) { + typeParam = TypeVarType.cloneForUnpacked(typeParam); + } + return options?.useBoundTypeVars ? TypeVarType.cloneAsBound(typeParam) : typeParam; }); return ClassType.specialize(type, typeParams); diff --git a/packages/pyright-internal/src/tests/samples/typeVarTuple30.py b/packages/pyright-internal/src/tests/samples/typeVarTuple30.py new file mode 100644 index 000000000000..8a33f999b841 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/typeVarTuple30.py @@ -0,0 +1,11 @@ +# This sample tests the case where a TypeVarTuple is used in a class +# and a `Self` type is involved. + +class Parent[*Ts]: + def __init__(self, *args: *Ts): ... + + def method(self): + Child(self) + + +class Child(Parent[*tuple[Parent, ...]]): ... diff --git a/packages/pyright-internal/src/tests/typeEvaluator6.test.ts b/packages/pyright-internal/src/tests/typeEvaluator6.test.ts index cd8f2e1cb8b1..5551158ef425 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator6.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator6.test.ts @@ -419,6 +419,14 @@ test('TypeVarTuple29', () => { TestUtils.validateResults(analysisResults, 0); }); +test('TypeVarTuple30', () => { + const configOptions = new ConfigOptions(Uri.empty()); + + configOptions.defaultPythonVersion = pythonVersion3_12; + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeVarTuple30.py'], configOptions); + TestUtils.validateResults(analysisResults, 0); +}); + test('Match1', () => { const configOptions = new ConfigOptions(Uri.empty());