Skip to content

Commit

Permalink
Fixed a bug that caused incorrect type inference for parameters in un…
Browse files Browse the repository at this point in the history
…annotated methods within child classes who derive from a generic parent class. This addresses a bug reported on stack overflow: https://stackoverflow.com/questions/76466874/trouble-specifying-type-parameter-when-inheriting-from-generic-class.
  • Loading branch information
msfterictraut committed Jun 20, 2023
1 parent 43c5fae commit eff69f5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16884,6 +16884,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
functionNode.parameters[paramIndex].category
);

// If the parameter type is generic, specialize it in the context
// of the child class.
if (requiresSpecialization(inferredParamType) && isClass(baseClassMemberInfo.classType)) {
const typeVarContext = buildTypeVarContextFromSpecializedClass(
baseClassMemberInfo.classType
);
inferredParamType = applySolvedTypeVars(inferredParamType, typeVarContext);
}

const fileInfo = AnalyzerNodeInfo.getFileInfo(functionNode);
if (fileInfo.isInPyTypedPackage && !fileInfo.isStubFile) {
inferredParamType = TypeBase.cloneForAmbiguousType(inferredParamType);
Expand Down
20 changes: 20 additions & 0 deletions packages/pyright-internal/src/tests/samples/paramInference2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This sample tests the logic that infers parameter types based on
# annotated base class methods when the base class is generic.


from typing import Generic, TypeVar

T = TypeVar("T")


class Parent(Generic[T]):
def method1(self, a: T, b: list[T]) -> None:
...


class Child(Parent[float]):
def method1(self, a, b):
reveal_type(self, expected_text="Self@Child")
reveal_type(a, expected_text="float")
reveal_type(b, expected_text="list[float]")
return a
6 changes: 6 additions & 0 deletions packages/pyright-internal/src/tests/typeEvaluator1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,12 @@ test('ParamInference1', () => {
TestUtils.validateResults(analysisResults, 0);
});

test('ParamInference2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['paramInference2.py']);

TestUtils.validateResults(analysisResults, 0);
});

test('Dictionary1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['dictionary1.py']);

Expand Down

0 comments on commit eff69f5

Please sign in to comment.