#90: Fixed false error for common arithmetic binary operators that act upon int/float/complex when operand is unioned with an unknown or any type.

This commit is contained in:
Eric Traut 2019-04-26 08:18:57 -07:00
parent c579ed6807
commit 2ec681e141
2 changed files with 16 additions and 3 deletions

View File

@ -1971,7 +1971,9 @@ export class ExpressionEvaluator {
const supportsBuiltInTypes = arithmeticOperatorMap[node.operator][2];
if (supportsBuiltInTypes) {
if (leftType instanceof ObjectType && rightType instanceof ObjectType) {
let simplifiedLeftType = TypeUtils.removeAnyFromUnion(leftType);
let simplifiedRightType = TypeUtils.removeAnyFromUnion(rightType);
if (simplifiedLeftType instanceof ObjectType && simplifiedRightType instanceof ObjectType) {
const builtInClassTypes = this._getBuiltInClassTypes(['int', 'float', 'complex']);
const getTypeMatch = (classType: ClassType): boolean[] => {
let foundMatch = false;
@ -1983,8 +1985,8 @@ export class ExpressionEvaluator {
});
};
const leftClassMatches = getTypeMatch(leftType.getClassType());
const rightClassMatches = getTypeMatch(rightType.getClassType());
const leftClassMatches = getTypeMatch(simplifiedLeftType.getClassType());
const rightClassMatches = getTypeMatch(simplifiedRightType.getClassType());
if (leftClassMatches[0] && rightClassMatches[0]) {
// If they're both int types, the result is an int.

View File

@ -850,6 +850,17 @@ export class TypeUtils {
return false;
}
// If the type is a union, it removes any "unknown" or "any" type
// from the union, returning only the known types.
static removeAnyFromUnion(type: Type): Type {
if (type instanceof UnionType) {
let remainingTypes = type.getTypes().filter(t => !t.isAny());
return this.combineTypes(remainingTypes);
}
return type;
}
// Filters a type such that that it is guaranteed not to
// be falsy. For example, if a type is a union of None
// and an "int", this method would strip off the "None"