mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-07 05:17:10 +03:00
Fixed false positive error related to heuristics employed in bidirectional type inference for calls when the expected type comprises a union and the return type of the call is a union that includes Any and a type variable.
This commit is contained in:
parent
2349041a68
commit
44451a99c8
@ -19130,6 +19130,20 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the special case where the dest is a union of Any and
|
||||
// a type variable and CanAssignFlags.AllowTypeVarNarrowing is
|
||||
// in effect. This occurs, for example, with the return type of
|
||||
// the getattr function.
|
||||
if ((flags & CanAssignFlags.AllowTypeVarNarrowing) !== 0 && isUnion(destType)) {
|
||||
const nonAnySubtypes = destType.subtypes.filter((t) => !isAnyOrUnknown(t));
|
||||
if (nonAnySubtypes.length === 1 && isTypeVar(nonAnySubtypes[0])) {
|
||||
canAssignType(nonAnySubtypes[0], srcType, /* diag */ undefined, typeVarMap, flags, recursionCount + 1);
|
||||
|
||||
// This always succeeds because the destination contains Any.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// For union sources, all of the types need to be assignable to the dest.
|
||||
let isIncompatible = false;
|
||||
doForEachSubtype(srcType, (subtype) => {
|
||||
|
@ -0,0 +1,15 @@
|
||||
# This sample tests a special case of bidirectional type inference when
|
||||
# the expected type is a union and the destination type is a union that
|
||||
# contains Any and a TypeVar.
|
||||
|
||||
|
||||
from typing import Any, Literal, TypeVar
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
def getattr(__o: object, name: str, __default: _T) -> Any | _T:
|
||||
...
|
||||
|
||||
|
||||
x: Literal[1, 2, 3] = getattr(object(), "", 1)
|
@ -757,6 +757,12 @@ test('GenericTypes71', () => {
|
||||
TestUtils.validateResults(analysisResults, 4);
|
||||
});
|
||||
|
||||
test('GenericTypes72', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['genericTypes72.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('Protocol1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['protocol1.py']);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user