Added diagnostic for __init__ method that does not have a return type of None.

This commit is contained in:
Eric Traut 2021-04-20 14:20:05 -07:00
parent 02de7c0f28
commit d659009c72
3 changed files with 40 additions and 0 deletions

View File

@ -438,6 +438,9 @@ export class Checker extends ParseTreeWalker {
if (functionTypeResult) {
// Validate that the function returns the declared type.
this._validateFunctionReturn(node, functionTypeResult.functionType);
// Verify common dunder signatures.
this._validateDunderSignatures(node, functionTypeResult.functionType, containingClassNode !== undefined);
}
// If we're at the module level within a stub file, report a diagnostic
@ -2520,6 +2523,41 @@ export class Checker extends ParseTreeWalker {
});
}
private _validateDunderSignatures(node: FunctionNode, functionType: FunctionType, isMethod: boolean) {
const functionName = functionType.details.name;
// Is this an '__init__' method? Verify that it returns None.
if (isMethod && functionName === '__init__') {
const returnAnnotation = node.returnTypeAnnotation || node.functionAnnotationComment?.returnTypeAnnotation;
const declaredReturnType = functionType.details.declaredReturnType;
if (returnAnnotation && declaredReturnType) {
if (!isNone(declaredReturnType)) {
this._evaluator.addDiagnostic(
this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues,
DiagnosticRule.reportGeneralTypeIssues,
Localizer.Diagnostic.initMustReturnNone(),
returnAnnotation
);
}
} else {
const inferredReturnType = this._evaluator.getFunctionInferredReturnType(functionType);
if (
!isNoReturnType(inferredReturnType) &&
!isNone(inferredReturnType) &&
!isAnyOrUnknown(inferredReturnType)
) {
this._evaluator.addDiagnostic(
this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues,
DiagnosticRule.reportGeneralTypeIssues,
Localizer.Diagnostic.initMustReturnNone(),
node.name
);
}
}
}
}
private _validateFunctionReturn(node: FunctionNode, functionType: FunctionType) {
// Stub files are allowed not to return an actual value,
// so skip this if it's a stub file.

View File

@ -378,6 +378,7 @@ export namespace Localizer {
);
export const inconsistentIndent = () => getRawString('Diagnostic.inconsistentIndent');
export const inconsistentTabs = () => getRawString('Diagnostic.inconsistentTabs');
export const initMustReturnNone = () => getRawString('Diagnostic.initMustReturnNone');
export const initSubclassClsParam = () => getRawString('Diagnostic.initSubclassClsParam');
export const instanceMethodSelfParam = () => getRawString('Diagnostic.instanceMethodSelfParam');
export const internalBindError = () =>

View File

@ -163,6 +163,7 @@
"importSymbolUnknown": "\"{name}\" is unknown import symbol",
"incompatibleMethodOverride": "Method \"{name}\" overrides class \"{className}\" in an incompatible manner",
"inconsistentIndent": "Unindent amount does not match previous indent",
"initMustReturnNone": "Return type of \"__init__\" must be None",
"inconsistentTabs": "Inconsistent use of tabs and spaces in indentation",
"initSubclassClsParam": "__init_subclass__ override should take a \"cls\" parameter",
"instanceMethodSelfParam": "Instance methods should take a \"self\" parameter",