diff --git a/docs/configuration.md b/docs/configuration.md index 6825a0e82..42ddbc646 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -94,6 +94,8 @@ The following settings control pyright’s diagnostic output (warnings or errors **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"`. + **reportInvalidTypeArguments** [boolean or string, optional]: Generate or suppress diagnostics for invalid type argument usage. 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"`. @@ -108,6 +110,8 @@ The following settings control pyright’s diagnostic output (warnings or errors **reportOptionalOperand** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to use an Optional type as an operand to a unary operator (like `~` or `not`) or the left-hand operator of a binary operator (like `*`, `==`, `or`). The default value for this setting is `"error"`. + **reportRedeclaration** [boolean or string, optional]: Generate or suppress diagnostics for a symbol that has more than one type declaration. The default value for this setting is `"error"`. + **reportTypedDictNotRequiredAccess** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to access a non-required field within a TypedDict without first checking whether it is present. The default value for this setting is `"error"`. **reportUntypedFunctionDecorator** [boolean or string, optional]: Generate or suppress diagnostics for function decorators that have no type annotations. These obscure the function type, defeating many type analysis features. The default value for this setting is `"none"`. @@ -336,6 +340,7 @@ The following table lists the default severity levels for each diagnostic rule w | reportAssertTypeFailure | "none" | "error" | "error" | "error" | | reportGeneralTypeIssues | "none" | "error" | "error" | "error" | | reportInconsistentOverload | "none" | "error" | "error" | "error" | +| reportInvalidTypeArguments | "none" | "error" | "error" | "error" | | reportNoOverloadImplementation | "none" | "error" | "error" | "error" | | reportOptionalSubscript | "none" | "error" | "error" | "error" | | reportOptionalMemberAccess | "none" | "error" | "error" | "error" | @@ -343,6 +348,7 @@ The following table lists the default severity levels for each diagnostic rule w | reportOptionalIterable | "none" | "error" | "error" | "error" | | reportOptionalContextManager | "none" | "error" | "error" | "error" | | reportOptionalOperand | "none" | "error" | "error" | "error" | +| reportRedeclaration | "none" | "error" | "error" | "error" | | reportTypedDictNotRequiredAccess | "none" | "error" | "error" | "error" | | reportPrivateImportUsage | "none" | "error" | "error" | "error" | | reportUnboundVariable | "none" | "error" | "error" | "error" | diff --git a/packages/pyright-internal/src/analyzer/checker.ts b/packages/pyright-internal/src/analyzer/checker.ts index a5345659b..0585cac4c 100644 --- a/packages/pyright-internal/src/analyzer/checker.ts +++ b/packages/pyright-internal/src/analyzer/checker.ts @@ -3193,7 +3193,7 @@ export class Checker extends ParseTreeWalker { decls.forEach((decl) => { if (decl !== typeAliasDecl) { this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportRedeclaration, LocMessage.typeAliasRedeclared().format({ name }), decl.node ); @@ -3317,7 +3317,7 @@ export class Checker extends ParseTreeWalker { if (!duplicateIsOk) { const diag = this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportRedeclaration, LocMessage.obscuredClassDeclaration().format({ name }), otherDecl.node.name ); @@ -3361,7 +3361,7 @@ export class Checker extends ParseTreeWalker { if (!duplicateIsOk) { const diag = this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportRedeclaration, otherDecl.isMethod ? LocMessage.obscuredMethodDeclaration().format({ name }) : LocMessage.obscuredFunctionDeclaration().format({ name }), @@ -3382,7 +3382,7 @@ export class Checker extends ParseTreeWalker { if (!duplicateIsOk) { const message = LocMessage.obscuredParameterDeclaration(); const diag = this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportRedeclaration, message.format({ name }), otherDecl.node.name ); @@ -3410,7 +3410,7 @@ export class Checker extends ParseTreeWalker { if (!duplicateIsOk) { const diag = this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportRedeclaration, LocMessage.obscuredVariableDeclaration().format({ name }), otherDecl.node ); @@ -3420,7 +3420,7 @@ export class Checker extends ParseTreeWalker { } } else if (otherDecl.type === DeclarationType.TypeAlias) { const diag = this._evaluator.addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportRedeclaration, LocMessage.obscuredTypeAliasDeclaration().format({ name }), otherDecl.node.name ); diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index 219d21760..3143e80d8 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -6879,7 +6879,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) { // If the class doesn't derive from Generic, a type argument should not be allowed. addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.typeArgsExpectingNone().format({ name: printType(ClassType.cloneAsInstance(concreteSubtype)), }), @@ -6981,7 +6981,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (concreteSubtype.typeArguments) { addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.classAlreadySpecialized().format({ type: printType(convertToInstance(concreteSubtype), { expandTypeAlias: true }), }), @@ -14712,7 +14712,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // Self doesn't support any type arguments. if (typeArgs) { addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.typeArgsExpectingNone().format({ name: classType.details.name, }), @@ -15193,7 +15193,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // is allowed if it's an unpacked variadic type var or tuple. None is also allowed // since it is used to define NoReturn in typeshed stubs). if (types.length === 1 && !allowSingleTypeArg && !isNoneInstance(types[0])) { - addDiagnostic(DiagnosticRule.reportGeneralTypeIssues, LocMessage.unionTypeArgCount(), errorNode); + addDiagnostic(DiagnosticRule.reportInvalidTypeArguments, LocMessage.unionTypeArgCount(), errorNode); } let unionType = combineTypes(types); @@ -19577,7 +19577,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (typeArgs[0].inlinedTypeDict) { if (typeArgs.length > 1) { addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.typeArgsTooMany().format({ name: classType.aliasName || classType.details.name, expected: 1, @@ -19592,7 +19592,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (!ClassType.isPartiallyEvaluated(classType) && !ClassType.isTupleClass(classType)) { if (typeParameters.length === 0) { addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.typeArgsExpectingNone().format({ name: classType.aliasName || classType.details.name, }), @@ -19600,7 +19600,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ); } else if (typeParameters.length !== 1 || !isParamSpec(typeParameters[0])) { addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.typeArgsTooMany().format({ name: classType.aliasName || classType.details.name, expected: typeParameters.length, @@ -19614,7 +19614,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } else if (typeArgCount < minTypeArgCount) { addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.typeArgsTooFew().format({ name: classType.aliasName || classType.details.name, expected: minTypeArgCount, @@ -19797,7 +19797,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (!isClassInstance(typeArgType) || !ClassType.isPartiallyEvaluated(typeArgType)) { assert(typeArgs !== undefined); addDiagnostic( - DiagnosticRule.reportGeneralTypeIssues, + DiagnosticRule.reportInvalidTypeArguments, LocMessage.typeVarAssignmentMismatch().format({ type: printType(typeArgType), name: TypeVarType.getReadableName(typeParameters[index]), diff --git a/packages/pyright-internal/src/common/configOptions.ts b/packages/pyright-internal/src/common/configOptions.ts index 00defa4af..1c3969b59 100644 --- a/packages/pyright-internal/src/common/configOptions.ts +++ b/packages/pyright-internal/src/common/configOptions.ts @@ -165,6 +165,9 @@ export interface DiagnosticRuleSet { // Report inconsistencies with function overload signatures? reportInconsistentOverload: DiagnosticLevel; + // Report invalid type argument usage? + reportInvalidTypeArguments: DiagnosticLevel; + // Report missing overloaded function implementation? reportNoOverloadImplementation: DiagnosticLevel; @@ -186,6 +189,9 @@ export interface DiagnosticRuleSet { // Report attempts to use an Optional type in a binary or unary operation? reportOptionalOperand: DiagnosticLevel; + // Report attempts to redeclare the type of a symbol? + reportRedeclaration: DiagnosticLevel; + // Report accesses to non-required TypedDict fields? reportTypedDictNotRequiredAccess: DiagnosticLevel; @@ -392,6 +398,7 @@ export function getDiagLevelDiagnosticRules() { DiagnosticRule.reportWildcardImportFromLibrary, DiagnosticRule.reportAssertTypeFailure, DiagnosticRule.reportInconsistentOverload, + DiagnosticRule.reportInvalidTypeArguments, DiagnosticRule.reportNoOverloadImplementation, DiagnosticRule.reportOptionalSubscript, DiagnosticRule.reportOptionalMemberAccess, @@ -399,6 +406,7 @@ export function getDiagLevelDiagnosticRules() { DiagnosticRule.reportOptionalIterable, DiagnosticRule.reportOptionalContextManager, DiagnosticRule.reportOptionalOperand, + DiagnosticRule.reportRedeclaration, DiagnosticRule.reportTypedDictNotRequiredAccess, DiagnosticRule.reportUntypedFunctionDecorator, DiagnosticRule.reportUntypedClassDecorator, @@ -487,6 +495,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet { reportWildcardImportFromLibrary: 'none', reportAssertTypeFailure: 'none', reportInconsistentOverload: 'none', + reportInvalidTypeArguments: 'none', reportNoOverloadImplementation: 'none', reportOptionalSubscript: 'none', reportOptionalMemberAccess: 'none', @@ -494,6 +503,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet { reportOptionalIterable: 'none', reportOptionalContextManager: 'none', reportOptionalOperand: 'none', + reportRedeclaration: 'none', reportTypedDictNotRequiredAccess: 'none', reportUntypedFunctionDecorator: 'none', reportUntypedClassDecorator: 'none', @@ -578,6 +588,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet { reportWildcardImportFromLibrary: 'warning', reportAssertTypeFailure: 'error', reportInconsistentOverload: 'error', + reportInvalidTypeArguments: 'error', reportNoOverloadImplementation: 'error', reportOptionalSubscript: 'error', reportOptionalMemberAccess: 'error', @@ -585,6 +596,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet { reportOptionalIterable: 'error', reportOptionalContextManager: 'error', reportOptionalOperand: 'error', + reportRedeclaration: 'error', reportTypedDictNotRequiredAccess: 'error', reportUntypedFunctionDecorator: 'none', reportUntypedClassDecorator: 'none', @@ -669,6 +681,7 @@ export function getStandardDiagnosticRuleSet(): DiagnosticRuleSet { reportWildcardImportFromLibrary: 'warning', reportAssertTypeFailure: 'error', reportInconsistentOverload: 'error', + reportInvalidTypeArguments: 'error', reportNoOverloadImplementation: 'error', reportOptionalSubscript: 'error', reportOptionalMemberAccess: 'error', @@ -676,6 +689,7 @@ export function getStandardDiagnosticRuleSet(): DiagnosticRuleSet { reportOptionalIterable: 'error', reportOptionalContextManager: 'error', reportOptionalOperand: 'error', + reportRedeclaration: 'error', reportTypedDictNotRequiredAccess: 'error', reportUntypedFunctionDecorator: 'none', reportUntypedClassDecorator: 'none', @@ -760,6 +774,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet { reportWildcardImportFromLibrary: 'error', reportAssertTypeFailure: 'error', reportInconsistentOverload: 'error', + reportInvalidTypeArguments: 'error', reportNoOverloadImplementation: 'error', reportOptionalSubscript: 'error', reportOptionalMemberAccess: 'error', @@ -767,6 +782,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet { reportOptionalIterable: 'error', reportOptionalContextManager: 'error', reportOptionalOperand: 'error', + reportRedeclaration: 'error', reportTypedDictNotRequiredAccess: 'error', reportUntypedFunctionDecorator: 'error', reportUntypedClassDecorator: 'error', diff --git a/packages/pyright-internal/src/common/diagnosticRules.ts b/packages/pyright-internal/src/common/diagnosticRules.ts index 35d87cb56..f354cd3cb 100644 --- a/packages/pyright-internal/src/common/diagnosticRules.ts +++ b/packages/pyright-internal/src/common/diagnosticRules.ts @@ -37,6 +37,7 @@ export enum DiagnosticRule { reportWildcardImportFromLibrary = 'reportWildcardImportFromLibrary', reportAssertTypeFailure = 'reportAssertTypeFailure', reportInconsistentOverload = 'reportInconsistentOverload', + reportInvalidTypeArguments = 'reportInvalidTypeArguments', reportNoOverloadImplementation = 'reportNoOverloadImplementation', reportOptionalSubscript = 'reportOptionalSubscript', reportOptionalMemberAccess = 'reportOptionalMemberAccess', @@ -44,6 +45,7 @@ export enum DiagnosticRule { reportOptionalIterable = 'reportOptionalIterable', reportOptionalContextManager = 'reportOptionalContextManager', reportOptionalOperand = 'reportOptionalOperand', + reportRedeclaration = 'reportRedeclaration', reportTypedDictNotRequiredAccess = 'reportTypedDictNotRequiredAccess', reportUntypedFunctionDecorator = 'reportUntypedFunctionDecorator', reportUntypedClassDecorator = 'reportUntypedClassDecorator', diff --git a/packages/vscode-pyright/package.json b/packages/vscode-pyright/package.json index 9f47ae355..d1331a3d4 100644 --- a/packages/vscode-pyright/package.json +++ b/packages/vscode-pyright/package.json @@ -447,6 +447,22 @@ false ] }, + "reportInvalidTypeArguments": { + "type": [ + "string", + "boolean" + ], + "description": "Diagnostics for invalid type argument usage.", + "default": "error", + "enum": [ + "none", + "information", + "warning", + "error", + true, + false + ] + }, "reportNoOverloadImplementation": { "type": [ "string", @@ -559,6 +575,22 @@ false ] }, + "reportRedeclaration": { + "type": [ + "string", + "boolean" + ], + "description": "Diagnostics for an attempt to declare the type of a symbol multiple times.", + "default": "error", + "enum": [ + "none", + "information", + "warning", + "error", + true, + false + ] + }, "reportTypedDictNotRequiredAccess": { "type": [ "string", diff --git a/packages/vscode-pyright/schemas/pyrightconfig.schema.json b/packages/vscode-pyright/schemas/pyrightconfig.schema.json index a03c5692d..2e735579f 100644 --- a/packages/vscode-pyright/schemas/pyrightconfig.schema.json +++ b/packages/vscode-pyright/schemas/pyrightconfig.schema.json @@ -263,6 +263,12 @@ "title": "Controls reporting of inconsistencies between function overload signatures", "default": "error" }, + "reportInvalidTypeArguments": { + "$id": "#/properties/reportInvalidTypeArguments", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting of invalid type argument usage", + "default": "error" + }, "reportNoOverloadImplementation": { "$id": "#/properties/reportNoOverloadImplementation", "$ref": "#/definitions/diagnostic", @@ -305,6 +311,12 @@ "title": "Controls reporting of attempts to use an Optional type as an operand for a binary or unary operator", "default": "error" }, + "reportRedeclaration": { + "$id": "#/properties/reportRedeclaration", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting of attempts to declare the type of a symbol multiple times", + "default": "error" + }, "reportTypedDictNotRequiredAccess": { "$id": "#/properties/reportTypedDictNotRequiredAccess", "$ref": "#/definitions/diagnostic",