Skip to content

Commit

Permalink
Fixed bug that results in a false positive when using a traditional (…
Browse files Browse the repository at this point in the history
…non-PEP 695) TypeVar in a type expression and assigning to a `TypeForm`. This addresses microsoft#9159. (microsoft#9160)
  • Loading branch information
erictraut authored Oct 6, 2024
1 parent f55ee0f commit 649a2ab
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 14 deletions.
14 changes: 7 additions & 7 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4684,6 +4684,10 @@ export function createTypeEvaluator(
type = validateSymbolIsTypeExpression(node, type, !!effectiveTypeInfo.includesVariableDecl);
}

if (isTypeVar(type) && !type.shared.isSynthesized) {
type = validateTypeVarUsage(node, type, flags);
}

// Add TypeForm details if appropriate.
type = addTypeFormForSymbol(node, type, flags, !!effectiveTypeInfo.includesVariableDecl);
} else {
Expand All @@ -4701,7 +4705,7 @@ export function createTypeEvaluator(
}
}

if (isParamSpec(type)) {
if (isParamSpec(type) && type.priv.scopeId) {
if (flags & EvalFlags.NoParamSpec) {
addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.paramSpecContext(), node);
type = UnknownType.create();
Expand All @@ -4722,10 +4726,6 @@ export function createTypeEvaluator(
}
}

if (isTypeVar(type) && !type.shared.isSynthesized) {
type = validateTypeVarUsage(node, type, flags);
}

return { type, isIncomplete };
}

Expand Down Expand Up @@ -4788,7 +4788,7 @@ export function createTypeEvaluator(
return true;
}

if (isTypeVar(type) && !type.priv.scopeId) {
if (isTypeVar(type)) {
return true;
}

Expand Down Expand Up @@ -5123,7 +5123,7 @@ export function createTypeEvaluator(
return type;
}

if (!type.shared.isSynthesized) {
if (!type.shared.isSynthesized && (flags & EvalFlags.InstantiableType) !== 0) {
const message = isParamSpec(type)
? LocMessage.paramSpecNotUsedByOuterScope()
: LocMessage.typeVarNotUsedByOuterScope();
Expand Down
5 changes: 2 additions & 3 deletions packages/pyright-internal/src/tests/samples/literals6.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
Wrong11 = Literal[...]


def func():
...
def func(): ...


Wrong12 = Literal[func]
Expand Down Expand Up @@ -59,7 +58,7 @@ def func():
# This should generate two errors.
var7: Literal[Path("abcd")]

# This should generate two errors.
# This should generate an error.
var8: Literal[T]

# This should generate an error.
Expand Down
2 changes: 1 addition & 1 deletion packages/pyright-internal/src/tests/samples/paramSpec12.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def union_args1(
) -> None:
pass

# This should generate an error because P.args cannot be used in
# This should generate two errors because P.args cannot be used in
# a union.
def union_args2(
*args: P.args | Sequence[Any], **kwargs: Union[P.kwargs, Mapping[str, Any]]
Expand Down
24 changes: 23 additions & 1 deletion packages/pyright-internal/src/tests/samples/typeForm2.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
Type,
TypeAlias,
TypeGuard,
TypeVar,
Union,
Unpack,
)
import typing as tp
from typing_extensions import TypeForm, TypeIs, ReadOnly

T = TypeVar("T")

type TA1 = int | str
type TA2[T] = list[T] | T
TA3: TypeAlias = Annotated[int, "meta"]
Expand Down Expand Up @@ -187,7 +190,26 @@ def func5():
reveal_type(t2, expected_text="TypeForm[TypeForm[TypeForm[int | str]]]")


def func6():
def func6(x: T) -> T:
v1: TypeForm[T] = T
v2 = tf(T)
reveal_type(v2, expected_text="TypeForm[T@func6]")

v3: TypeForm[T | int] = T
v3 = T | int

v4 = tf(T | int)
reveal_type(v4, expected_text="TypeForm[T@func6 | int]")

v5: TypeForm[list[T]] = list[T]

v6 = tf(list[T])
reveal_type(v6, expected_text="TypeForm[list[T@func6]]")

return x


def func7():
# This should generate an error.
t1 = tf(Generic)

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 @@ -596,7 +596,7 @@ test('Literals5', () => {
test('Literals6', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['literals6.py']);

TestUtils.validateResults(analysisResults, 26);
TestUtils.validateResults(analysisResults, 25);
});

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

test('ParamSpec12', () => {
const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec12.py']);
TestUtils.validateResults(results, 15);
TestUtils.validateResults(results, 14);
});

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

0 comments on commit 649a2ab

Please sign in to comment.