Improved handling of constrained TypeVars when used with unary operators. This addresses #7874. (#7900)

This commit is contained in:
Eric Traut 2024-05-12 21:51:16 -07:00 committed by GitHub
parent 5817d275a2
commit f7aba4ede4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 1 deletions

View File

@ -1031,7 +1031,27 @@ export function getTypeOfUnaryOperation(
type = exprType;
} else {
const magicMethodName = unaryOperatorMap[node.operator];
type = evaluator.getTypeOfMagicMethodCall(exprType, magicMethodName, [], node, inferenceContext);
let isResultValid = true;
type = evaluator.mapSubtypesExpandTypeVars(exprType, /* options */ undefined, (subtypeExpanded) => {
const result = evaluator.getTypeOfMagicMethodCall(
subtypeExpanded,
magicMethodName,
[],
node,
inferenceContext
);
if (!result) {
isResultValid = false;
}
return result;
});
if (!isResultValid) {
type = undefined;
}
}
if (!type) {

View File

@ -0,0 +1,14 @@
# This sample tests the handling of operators when used with constrained
# type variables.
from typing import Generic, TypeVar
T = TypeVar("T", int, float)
class A(Generic[T]):
def __init__(self, x: T):
self.x: T = x
def __neg__(self) -> "A[T]":
return A[T](x=-self.x)

View File

@ -383,6 +383,12 @@ test('Operator11', () => {
TestUtils.validateResults(analysisResults, 0);
});
test('Operator12', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['operator12.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('Optional1', () => {
const configOptions = new ConfigOptions(Uri.empty());