diff --git a/docs/configuration.md b/docs/configuration.md index e23d09fc0..6825a0e82 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -92,6 +92,10 @@ The following settings control pyright’s diagnostic output (warnings or errors **reportAssertTypeFailure** [boolean or string, optional]: Generate or suppress diagnostics for a type mismatch detected by the `typing.assert_type` call. The default value for this setting is `"error"`. + **reportInconsistentOverload** [boolean or string, optional]: Generate or suppress diagnostics for an overloaded function that has overload signatures that are inconsistent with each other or with the implementation. The default value for this setting is `"error"`. + + **reportNoOverloadImplementation** [boolean or string, optional]: Generate or suppress diagnostics for an overloaded function or method if the implementation is not provided. The default value for this setting is `"error"`. + **reportOptionalSubscript** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to subscript (index) a variable with an Optional type. The default value for this setting is `"error"`. **reportOptionalMemberAccess** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to access a member of a variable with an Optional type. The default value for this setting is `"error"`. @@ -331,6 +335,8 @@ The following table lists the default severity levels for each diagnostic rule w | reportWildcardImportFromLibrary | "none" | "warning" | "warning" | "error" | | reportAssertTypeFailure | "none" | "error" | "error" | "error" | | reportGeneralTypeIssues | "none" | "error" | "error" | "error" | +| reportInconsistentOverload | "none" | "error" | "error" | "error" | +| reportNoOverloadImplementation | "none" | "error" | "error" | "error" | | reportOptionalSubscript | "none" | "error" | "error" | "error" | | reportOptionalMemberAccess | "none" | "error" | "error" | "error" | | reportOptionalCall | "none" | "error" | "error" | "error" | diff --git a/packages/pyright-internal/src/analyzer/checker.ts b/packages/pyright-internal/src/analyzer/checker.ts index 81d81e961..a5345659b 100644 --- a/packages/pyright-internal/src/analyzer/checker.ts +++ b/packages/pyright-internal/src/analyzer/checker.ts @@ -2575,7 +2575,7 @@ export class Checker extends ParseTreeWalker { if (staticMethodCount > 0 && staticMethodCount < functionType.overloads.length) { this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInconsistentOverload, LocMessage.overloadStaticMethodInconsistent().format({ name: node.name.value, }), @@ -2585,7 +2585,7 @@ export class Checker extends ParseTreeWalker { if (classMethodCount > 0 && classMethodCount < functionType.overloads.length) { this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInconsistentOverload, LocMessage.overloadClassMethodInconsistent().format({ name: node.name.value, }), @@ -3023,7 +3023,7 @@ export class Checker extends ParseTreeWalker { if (overloadedFunctions.length === 1) { // There should never be a single overload. this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInconsistentOverload, LocMessage.singleOverload().format({ name }), primaryDecl.node.name ); @@ -3066,7 +3066,7 @@ export class Checker extends ParseTreeWalker { // there is an implementation. if (!exemptMissingImplementation) { this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportNoOverloadImplementation, LocMessage.overloadWithoutImplementation().format({ name: primaryDecl.node.name.value, }), @@ -3080,7 +3080,7 @@ export class Checker extends ParseTreeWalker { if (!this._isLegalOverloadImplementation(overload, implementationFunction!, diag)) { if (implementationFunction!.details.declaration) { const diagnostic = this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInconsistentOverload, LocMessage.overloadImplementationMismatch().format({ name, index: index + 1, @@ -5869,7 +5869,7 @@ export class Checker extends ParseTreeWalker { overloads.forEach((overload) => { if (FunctionType.isFinal(overload) && overload.details.declaration?.node) { this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInconsistentOverload, LocMessage.overloadFinalInconsistencyImpl().format({ name: overload.details.name, }), @@ -5886,7 +5886,7 @@ export class Checker extends ParseTreeWalker { overloads.slice(1).forEach((overload, index) => { if (FunctionType.isFinal(overload) && overload.details.declaration?.node) { this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInconsistentOverload, LocMessage.overloadFinalInconsistencyNoImpl().format({ name: overload.details.name, index: index + 2, diff --git a/packages/pyright-internal/src/analyzer/decorators.ts b/packages/pyright-internal/src/analyzer/decorators.ts index e283f6721..c10a7727a 100644 --- a/packages/pyright-internal/src/analyzer/decorators.ts +++ b/packages/pyright-internal/src/analyzer/decorators.ts @@ -573,7 +573,7 @@ export function addOverloadsToFunctionType(evaluator: TypeEvaluator, node: Funct if (isPrevOverloadAbstract !== isCurrentOverloadAbstract) { evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInconsistentOverload, LocMessage.overloadAbstractMismatch().format({ name: node.name.value }), node.name ); diff --git a/packages/pyright-internal/src/common/configOptions.ts b/packages/pyright-internal/src/common/configOptions.ts index dbfaf87a0..00defa4af 100644 --- a/packages/pyright-internal/src/common/configOptions.ts +++ b/packages/pyright-internal/src/common/configOptions.ts @@ -162,6 +162,12 @@ export interface DiagnosticRuleSet { // Report failure of assert_type call? reportAssertTypeFailure: DiagnosticLevel; + // Report inconsistencies with function overload signatures? + reportInconsistentOverload: DiagnosticLevel; + + // Report missing overloaded function implementation? + reportNoOverloadImplementation: DiagnosticLevel; + // Report attempts to subscript (index) an Optional type? reportOptionalSubscript: DiagnosticLevel; @@ -385,6 +391,8 @@ export function getDiagLevelDiagnosticRules() { DiagnosticRule.reportDuplicateImport, DiagnosticRule.reportWildcardImportFromLibrary, DiagnosticRule.reportAssertTypeFailure, + DiagnosticRule.reportInconsistentOverload, + DiagnosticRule.reportNoOverloadImplementation, DiagnosticRule.reportOptionalSubscript, DiagnosticRule.reportOptionalMemberAccess, DiagnosticRule.reportOptionalCall, @@ -478,6 +486,8 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet { reportDuplicateImport: 'none', reportWildcardImportFromLibrary: 'none', reportAssertTypeFailure: 'none', + reportInconsistentOverload: 'none', + reportNoOverloadImplementation: 'none', reportOptionalSubscript: 'none', reportOptionalMemberAccess: 'none', reportOptionalCall: 'none', @@ -567,6 +577,8 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet { reportDuplicateImport: 'none', reportWildcardImportFromLibrary: 'warning', reportAssertTypeFailure: 'error', + reportInconsistentOverload: 'error', + reportNoOverloadImplementation: 'error', reportOptionalSubscript: 'error', reportOptionalMemberAccess: 'error', reportOptionalCall: 'error', @@ -656,6 +668,8 @@ export function getStandardDiagnosticRuleSet(): DiagnosticRuleSet { reportDuplicateImport: 'none', reportWildcardImportFromLibrary: 'warning', reportAssertTypeFailure: 'error', + reportInconsistentOverload: 'error', + reportNoOverloadImplementation: 'error', reportOptionalSubscript: 'error', reportOptionalMemberAccess: 'error', reportOptionalCall: 'error', @@ -745,6 +759,8 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet { reportDuplicateImport: 'error', reportWildcardImportFromLibrary: 'error', reportAssertTypeFailure: 'error', + reportInconsistentOverload: 'error', + reportNoOverloadImplementation: 'error', reportOptionalSubscript: 'error', reportOptionalMemberAccess: 'error', reportOptionalCall: 'error', diff --git a/packages/pyright-internal/src/common/diagnosticRules.ts b/packages/pyright-internal/src/common/diagnosticRules.ts index 5e80f8e7d..35d87cb56 100644 --- a/packages/pyright-internal/src/common/diagnosticRules.ts +++ b/packages/pyright-internal/src/common/diagnosticRules.ts @@ -36,6 +36,8 @@ export enum DiagnosticRule { reportDuplicateImport = 'reportDuplicateImport', reportWildcardImportFromLibrary = 'reportWildcardImportFromLibrary', reportAssertTypeFailure = 'reportAssertTypeFailure', + reportInconsistentOverload = 'reportInconsistentOverload', + reportNoOverloadImplementation = 'reportNoOverloadImplementation', reportOptionalSubscript = 'reportOptionalSubscript', reportOptionalMemberAccess = 'reportOptionalMemberAccess', reportOptionalCall = 'reportOptionalCall', diff --git a/packages/vscode-pyright/package.json b/packages/vscode-pyright/package.json index dc58b7cf0..9f47ae355 100644 --- a/packages/vscode-pyright/package.json +++ b/packages/vscode-pyright/package.json @@ -431,6 +431,38 @@ false ] }, + "reportInconsistentOverload": { + "type": [ + "string", + "boolean" + ], + "description": "Diagnostics for inconsistencies between function overload signatures and implementation.", + "default": "error", + "enum": [ + "none", + "information", + "warning", + "error", + true, + false + ] + }, + "reportNoOverloadImplementation": { + "type": [ + "string", + "boolean" + ], + "description": "Diagnostics for an overloaded function or method with a missing implementation.", + "default": "error", + "enum": [ + "none", + "information", + "warning", + "error", + true, + false + ] + }, "reportOptionalSubscript": { "type": [ "string", diff --git a/packages/vscode-pyright/schemas/pyrightconfig.schema.json b/packages/vscode-pyright/schemas/pyrightconfig.schema.json index 1f35ba6b5..a03c5692d 100644 --- a/packages/vscode-pyright/schemas/pyrightconfig.schema.json +++ b/packages/vscode-pyright/schemas/pyrightconfig.schema.json @@ -257,6 +257,18 @@ "title": "Controls reporting of type mismatch detected by typing.assert_type call", "default": "error" }, + "reportInconsistentOverload": { + "$id": "#/properties/reportInconsistentOverload", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting of inconsistencies between function overload signatures", + "default": "error" + }, + "reportNoOverloadImplementation": { + "$id": "#/properties/reportNoOverloadImplementation", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting of an overloaded function or method with a missing implementation", + "default": "error" + }, "reportOptionalSubscript": { "$id": "#/properties/reportOptionalSubscript", "$ref": "#/definitions/diagnostic",