From 186e4446527734b27c3fa5661fd8fb619df25126 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 15 May 2021 19:23:25 -0700 Subject: [PATCH] Added new diagnostic rule "reportIncompleteStub", which reports a diagnostic for a module-level `__getattr__` function in a type stub, indicating that it's incomplete. This check was previously part of the "reportUnknownMemberType" diagnostic rule. --- docs/configuration.md | 3 +++ packages/pyright-internal/src/analyzer/checker.ts | 4 ++-- .../pyright-internal/src/common/configOptions.ts | 14 ++++++++++++++ .../pyright-internal/src/common/diagnosticRules.ts | 1 + packages/vscode-pyright/package.json | 13 ++++++++++++- .../schemas/pyrightconfig.schema.json | 6 ++++++ 6 files changed, 38 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 5630f0f6e..ff4b42f98 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -146,6 +146,8 @@ The following settings control pyright’s diagnostic output (warnings or errors **reportInvalidStubStatement** [boolean or string, optional]: Generate or suppress diagnostics for statements that are syntactically correct but have no purpose within a type stub file. The default value for this setting is 'none'. +**reportIncompleteStub** [boolean or string, optional]: Generate or suppress diagnostics for a module-level `__getattr__` call in a type stub file, indicating that it is incomplete. The default value for this setting is 'none'. + **reportUnsupportedDunderAll** [boolean or string, optional]: Generate or suppress diagnostics for statements that define or manipulate `__all__` in a way that is not allowed by a static type checker, thus rendering the contents of `__all__` to be unknown or incorrect. The default value for this setting is 'warning'. **reportUnusedCallResult** [boolean or string, optional]: Generate or suppress diagnostics for call statements whose return value is not used in any way and is not None. The default value for this setting is 'none'. @@ -311,6 +313,7 @@ The following table lists the default severity levels for each diagnostic rule w | reportUndefinedVariable | "warning" | "error" | "error" | | reportUnboundVariable | "none" | "error" | "error" | | reportInvalidStubStatement | "none" | "none" | "error" | +| reportIncompleteStub | "none" | "none" | "error" | | reportUnsupportedDunderAll | "none" | "warning" | "error" | | reportUnusedCallResult | "none" | "none" | "none" | | reportUnusedCoroutine | "none" | "error" | "error" | diff --git a/packages/pyright-internal/src/analyzer/checker.ts b/packages/pyright-internal/src/analyzer/checker.ts index 8564af181..c8999747f 100644 --- a/packages/pyright-internal/src/analyzer/checker.ts +++ b/packages/pyright-internal/src/analyzer/checker.ts @@ -453,8 +453,8 @@ export class Checker extends ParseTreeWalker { const scope = getScopeForNode(node); if (scope?.type === ScopeType.Module) { this._evaluator.addDiagnostic( - this._fileInfo.diagnosticRuleSet.reportUnknownMemberType, - DiagnosticRule.reportUnknownMemberType, + this._fileInfo.diagnosticRuleSet.reportIncompleteStub, + DiagnosticRule.reportIncompleteStub, Localizer.Diagnostic.stubUsesGetAttr(), node.name ); diff --git a/packages/pyright-internal/src/common/configOptions.ts b/packages/pyright-internal/src/common/configOptions.ts index 91554fbc7..eadfdecca 100644 --- a/packages/pyright-internal/src/common/configOptions.ts +++ b/packages/pyright-internal/src/common/configOptions.ts @@ -245,6 +245,9 @@ export interface DiagnosticRuleSet { // have no semantic meaning within a type stub file. reportInvalidStubStatement: DiagnosticLevel; + // Report usage of __getattr__ at the module level in a stub. + reportIncompleteStub: DiagnosticLevel; + // Report operations on __all__ symbol that are not supported // by a static type checker. reportUnsupportedDunderAll: DiagnosticLevel; @@ -326,6 +329,7 @@ export function getDiagLevelDiagnosticRules() { DiagnosticRule.reportUndefinedVariable, DiagnosticRule.reportUnboundVariable, DiagnosticRule.reportInvalidStubStatement, + DiagnosticRule.reportIncompleteStub, DiagnosticRule.reportUnsupportedDunderAll, DiagnosticRule.reportUnusedCallResult, DiagnosticRule.reportUnusedCoroutine, @@ -396,6 +400,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet { reportUnboundVariable: 'none', reportUndefinedVariable: 'warning', reportInvalidStubStatement: 'none', + reportIncompleteStub: 'none', reportUnsupportedDunderAll: 'none', reportUnusedCallResult: 'none', reportUnusedCoroutine: 'none', @@ -462,6 +467,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet { reportUnboundVariable: 'error', reportUndefinedVariable: 'error', reportInvalidStubStatement: 'none', + reportIncompleteStub: 'none', reportUnsupportedDunderAll: 'warning', reportUnusedCallResult: 'none', reportUnusedCoroutine: 'error', @@ -528,6 +534,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet { reportUnboundVariable: 'error', reportUndefinedVariable: 'error', reportInvalidStubStatement: 'error', + reportIncompleteStub: 'error', reportUnsupportedDunderAll: 'error', reportUnusedCallResult: 'none', reportUnusedCoroutine: 'error', @@ -1188,6 +1195,13 @@ export class ConfigOptions { defaultSettings.reportInvalidStubStatement ), + // Read the "reportIncompleteStub" entry. + reportIncompleteStub: this._convertDiagnosticLevel( + configObj.reportIncompleteStub, + DiagnosticRule.reportIncompleteStub, + defaultSettings.reportIncompleteStub + ), + // Read the "reportUnsupportedDunderAll" entry. reportUnsupportedDunderAll: this._convertDiagnosticLevel( configObj.reportUnsupportedDunderAll, diff --git a/packages/pyright-internal/src/common/diagnosticRules.ts b/packages/pyright-internal/src/common/diagnosticRules.ts index afdbb2a90..4f2e59461 100644 --- a/packages/pyright-internal/src/common/diagnosticRules.ts +++ b/packages/pyright-internal/src/common/diagnosticRules.ts @@ -64,6 +64,7 @@ export enum DiagnosticRule { reportUndefinedVariable = 'reportUndefinedVariable', reportUnboundVariable = 'reportUnboundVariable', reportInvalidStubStatement = 'reportInvalidStubStatement', + reportIncompleteStub = 'reportIncompleteStub', reportUnsupportedDunderAll = 'reportUnsupportedDunderAll', reportUnusedCallResult = 'reportUnusedCallResult', reportUnusedCoroutine = 'reportUnusedCoroutine', diff --git a/packages/vscode-pyright/package.json b/packages/vscode-pyright/package.json index 762b994ab..42b1e8ee0 100644 --- a/packages/vscode-pyright/package.json +++ b/packages/vscode-pyright/package.json @@ -600,7 +600,18 @@ }, "reportInvalidStubStatement": { "type": "string", - "description": "Diagnostics for type stub statements that do not conform to PEP 484", + "description": "Diagnostics for type stub statements that do not conform to PEP 484.", + "default": "none", + "enum": [ + "none", + "information", + "warning", + "error" + ] + }, + "reportIncompleteStub": { + "type": "string", + "description": "Diagnostics for the use of a module-level “__getattr__” function, indicating that the stub is incomplete.", "default": "none", "enum": [ "none", diff --git a/packages/vscode-pyright/schemas/pyrightconfig.schema.json b/packages/vscode-pyright/schemas/pyrightconfig.schema.json index 5e86746e3..3d7d3f6f7 100644 --- a/packages/vscode-pyright/schemas/pyrightconfig.schema.json +++ b/packages/vscode-pyright/schemas/pyrightconfig.schema.json @@ -413,6 +413,12 @@ "title": "Controls reporting of type stub statements that do not conform to PEP 484", "default": "none" }, + "reportIncompleteStub": { + "$id": "#/properties/reportIncompleteStub", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting of incomplete type stubs that declare a module-level __getattr__ function", + "default": "none" + }, "reportUnsupportedDunderAll": { "$id": "#/properties/reportUnsupportedDunderAll", "$ref": "#/definitions/diagnostic",