Implemented support for bidirectional type inference when an assignment has a LHS consisting of an index expression.

This commit is contained in:
Eric Traut 2019-10-18 01:11:08 -07:00
parent 51aa8d9869
commit adca930c59
3 changed files with 39 additions and 0 deletions

View File

@ -1892,6 +1892,21 @@ export class TypeAnalyzer extends ParseTreeWalker {
if (classMemberInfo) {
symbol = classMemberInfo.symbol;
}
} else if (expression.nodeType === ParseNodeType.Index) {
const baseType = this._getTypeOfExpression(expression.baseExpression, EvaluatorFlags.None, true);
if (baseType.category === TypeCategory.Object) {
const setItemMember = TypeUtils.lookUpClassMember(baseType.classType, '__setitem__');
if (setItemMember) {
if (setItemMember.symbolType.category === TypeCategory.Function) {
const boundFunction = TypeUtils.bindFunctionToClassOrObject(baseType, setItemMember.symbolType);
if (boundFunction.category === TypeCategory.Function) {
if (boundFunction.details.parameters.length === 2) {
return FunctionType.getEffectiveParameterType(boundFunction, 1);
}
}
}
}
}
}
if (symbol) {

View File

@ -0,0 +1,18 @@
# This sample tests various assignment scenarios where
# there is an expected type, so bidirectional type
# inference is used.
# pyright: strict
from typing import Dict, Callable, Sequence, Tuple
AAA = float
BBB = int
CCC = str
DDD = str
AAATuple = Tuple[AAA, BBB, Callable[[Sequence[int], AAA], Sequence[float]]]
def foo():
var1: Dict[str, Tuple[AAA, BBB, CCC, DDD]] = {}
var2: Dict[str, AAATuple] = {}
for k, (var3, var4, _, _) in var1.items():
var2[k] = (var3, var4, lambda var5, var6: [v * var6 for v in var5])

View File

@ -565,6 +565,12 @@ test('Assignment3', () => {
validateResults(analysisResults, 4);
});
test('Assignment4', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['assignment4.py']);
validateResults(analysisResults, 0);
});
test('AugmentedAssignment1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['augmentedAssignment1.py']);