Skip to content

Commit

Permalink
Fixed a recent regression that resulted in unsolved type arguments wh…
Browse files Browse the repository at this point in the history
…en a "bare" generic class (like `dict`) is passed as an argument to a function that accepts a `type[T]`. This addresses #5392.
  • Loading branch information
msfterictraut committed Jul 13, 2023
1 parent 752b24a commit 4d92540
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
10 changes: 8 additions & 2 deletions packages/pyright-internal/src/analyzer/constraintSolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,14 @@ export function assignTypeToTypeVar(
// If the source is a class that is missing type arguments, fill
// in missing type arguments with Unknown.
if ((flags & AssignTypeFlags.AllowUnspecifiedTypeArguments) === 0) {
if (isClass(adjSrcType) && adjSrcType.includeSubclasses) {
adjSrcType = specializeWithDefaultTypeArgs(adjSrcType);
if (isClass(adjSrcType)) {
// Skip this if the source is a concrete class and the dest is
// not a type[T]. This combination is used for class decorators
// such as dataclass_transform, and we need to retain the original
// unspecialized class in this case.
if (adjSrcType.includeSubclasses || TypeBase.isInstantiable(destType)) {
adjSrcType = specializeWithDefaultTypeArgs(adjSrcType);
}
}
}

Expand Down
23 changes: 23 additions & 0 deletions packages/pyright-internal/src/tests/samples/solver27.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This sample tests that the assignment of an instantiable generic class
# without supplied type arguments is given default type arguments (typically
# Unknown) when the TypeVar is solved.

from typing import Any, TypeVar, reveal_type

T = TypeVar("T")


def deco1(t: type[T], val: Any) -> T:
return val


v1 = deco1(dict, {"foo": "bar"})
reveal_type(v1, expected_text="dict[Unknown, Unknown]")


def deco2(t: T, val: Any) -> T:
return val


v2 = deco2(dict, {"foo": "bar"})
reveal_type(v2, expected_text="type[dict[Unknown, Unknown]]")
6 changes: 6 additions & 0 deletions packages/pyright-internal/src/tests/typeEvaluator2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,12 @@ test('Solver26', () => {
TestUtils.validateResults(analysisResults, 0);
});

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

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

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

Expand Down

0 comments on commit 4d92540

Please sign in to comment.