Modified behavior in constructor call code that previously applied some (now non-compliant) heuristics to reconcile a metaclass __call__ method with a __new__ method. The new behavior is now compliant with the typing spec.

This commit is contained in:
Eric Traut 2024-04-13 21:07:40 -07:00
parent 9d87fe1079
commit 653e1609e7

View File

@ -149,7 +149,7 @@ export function validateConstructorArguments(
// If there is a constructor transform, evaluate all arguments speculatively
// so we can later re-evaluate them in the context of the transform.
let returnResult = evaluator.useSpeculativeMode(useConstructorTransform ? errorNode : undefined, () => {
const returnResult = evaluator.useSpeculativeMode(useConstructorTransform ? errorNode : undefined, () => {
return validateNewAndInitMethods(
evaluator,
errorNode,
@ -211,21 +211,6 @@ export function validateConstructorArguments(
});
}
// Reconcile the metaclass __call__ return type and the __new__ return type.
// This is a heuristic because we have no way of knowing how these actually
// interact based on the method signatures alone.
if (metaclassResult?.returnType) {
// If the __new__ and __init__ methods returned `Any` or `Unknown` or `NoReturn`,
// use the metaclass return type instead.
if (!returnResult.returnType || isAnyOrUnknown(returnResult.returnType)) {
if (!isAnyOrUnknown(metaclassResult.returnType)) {
returnResult = { ...returnResult, returnType: metaclassResult.returnType };
}
} else if (returnResult.returnType && isNever(returnResult.returnType)) {
returnResult = { ...returnResult, returnType: metaclassResult.returnType };
}
}
return returnResult;
}