Fixed translation of a heterogenous tuple into an iterator. The resulting iterator needs to have a type argument created from a union of the heterogeneous tuple entries.

This commit is contained in:
Eric Traut 2020-02-15 01:21:55 -07:00
parent 8bed8ed079
commit f866c033b8
3 changed files with 38 additions and 1 deletions

View File

@ -720,7 +720,21 @@ export function setTypeArgumentsRecursive(destType: Type, srcType: Type,
// _T1 with str and _T2 with int. // _T1 with str and _T2 with int.
export function buildTypeVarMapFromSpecializedClass(classType: ClassType): TypeVarMap { export function buildTypeVarMapFromSpecializedClass(classType: ClassType): TypeVarMap {
const typeParameters = ClassType.getTypeParameters(classType); const typeParameters = ClassType.getTypeParameters(classType);
return buildTypeVarMap(typeParameters, classType.typeArguments); let typeArguments = classType.typeArguments;
// Handle the special case where the source is a Tuple with heterogenous
// type arguments. In this case, we'll create a union out of the heterogeneous
// types.
if (ClassType.isBuiltIn(classType, 'Tuple') && classType.typeArguments) {
if (classType.typeArguments.length > 1) {
const lastTypeArg = classType.typeArguments[classType.typeArguments.length - 1];
if (!isEllipsisType(lastTypeArg)) {
typeArguments = [combineTypes(classType.typeArguments)];
}
}
}
return buildTypeVarMap(typeParameters, typeArguments);
} }
export function buildTypeVarMap(typeParameters: TypeVarType[], typeArgs: Type[] | undefined): TypeVarMap { export function buildTypeVarMap(typeParameters: TypeVarType[], typeArgs: Type[] | undefined): TypeVarMap {

View File

@ -430,6 +430,12 @@ test('Tuples3', () => {
validateResults(analysisResults, 2); validateResults(analysisResults, 2);
}); });
test('Tuples4', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['tuples4.py']);
validateResults(analysisResults, 0);
});
test('NamedTuples1', () => { test('NamedTuples1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['namedTuples1.py']); const analysisResults = TestUtils.typeAnalyzeSampleFiles(['namedTuples1.py']);

View File

@ -0,0 +1,17 @@
# This sample tests the translation of a heterogenous tuple
# into an Interable.
from typing import Iterable, Iterator, List, Tuple, TypeVar, Union
_T = TypeVar('_T')
def foo(x: Iterable[_T]):
return x
def bar(x: Iterable[Union[int, str]]): pass
my_tuple = (3, 'hello')
# The type of my_iterable should be Iterable[Union[int, str]].
my_iterable = foo(my_tuple)
bar(my_iterable)