mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Changed behavior of constructor call evaluation when __new__
evaluation results in type evaluation errors. Previously, pyright skipped the __init__
evaluation in this case. It now proceeds to evaluate __init__
, potentially generating redundant errors. This addresses #8026. (#8029)
This commit is contained in:
parent
2e397e9a0a
commit
32fa85e3ed
@ -292,9 +292,17 @@ function validateNewAndInitMethods(
|
||||
|
||||
let initMethodTypeResult: TypeResult | undefined;
|
||||
|
||||
// Validate __init__ if it's present. Skip if the __new__ method produced errors.
|
||||
// If there were errors evaluating the __new__ method, assume that __new__
|
||||
// returns the class instance and proceed accordingly. This may produce
|
||||
// false positives in some cases, but it will prevent false negatives
|
||||
// if the __init__ method also produces type errors (perhaps unrelated
|
||||
// to the errors in the __new__ method).
|
||||
if (argumentErrors) {
|
||||
initMethodTypeResult = { type: convertToInstance(type) };
|
||||
}
|
||||
|
||||
// Validate __init__ if it's present.
|
||||
if (
|
||||
!argumentErrors &&
|
||||
!isNever(newMethodReturnType) &&
|
||||
!shouldSkipInitEvaluation(evaluator, type, newMethodReturnType) &&
|
||||
isClassInstance(newMethodReturnType)
|
||||
|
@ -13177,7 +13177,7 @@ export function createTypeEvaluator(
|
||||
if (isEffectivelyInstantiable(specializedType)) {
|
||||
classType.details.baseClasses.push(specializedType);
|
||||
} else {
|
||||
addExpectedClassDiagnostic(typeArg.type, argList[1].valueExpression || errorNode);
|
||||
classType.details.baseClasses.push(UnknownType.create());
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -13,13 +13,16 @@ class A(X1): ...
|
||||
class B(X2, A): ...
|
||||
|
||||
|
||||
# This should generate an error because the first arg is not a string.
|
||||
# This should generate two errors (one for `__new__` and one for `__init__`)
|
||||
# because the first arg is not a string.
|
||||
X3 = type(34, (object,))
|
||||
|
||||
# This should generate an error because the second arg is not a tuple of class types.
|
||||
# This should generate two errors (one for `__new__` and one for `__init__`)
|
||||
# because the second arg is not a tuple of class types.
|
||||
X4 = type("X4", 34)
|
||||
|
||||
# This should generate an error because the second arg is not a tuple of class types.
|
||||
# This should generate two errors (one for `__new__` and one for `__init__`)
|
||||
# because the second arg is not a tuple of class types.
|
||||
X5 = type("X5", (3,))
|
||||
|
||||
|
||||
|
@ -266,7 +266,7 @@ test('NewType1', () => {
|
||||
test('NewType2', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['newType2.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 4);
|
||||
TestUtils.validateResults(analysisResults, 6);
|
||||
});
|
||||
|
||||
test('NewType3', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user