mirror of
https://github.com/microsoft/pyright.git
synced 2024-08-17 03:40:44 +03:00
Added new diagnostic rule "reportInvalidStubStatement" (on by default in strict mode, off otherwise) that reports diagnostics for statements that should not appear within a type stub file.
This commit is contained in:
parent
77cd54e4d2
commit
109e2dfd71
@ -345,6 +345,12 @@
|
||||
"title": "Controls reporting usage of implicit concatenation of string literals",
|
||||
"default": "warning"
|
||||
},
|
||||
"reportInvalidStubStatement": {
|
||||
"$id": "#/properties/reportInvalidStubStatement",
|
||||
"$ref": "#/definitions/diagnostic",
|
||||
"title": "Controls reporting of statements that have no semantic meaning within a type stub",
|
||||
"default": "none"
|
||||
},
|
||||
"pythonVersion": {
|
||||
"$id": "#/properties/pythonVersion",
|
||||
"type": "string",
|
||||
|
@ -120,6 +120,8 @@ The following settings control pyright’s diagnostic output (warnings or errors
|
||||
|
||||
**reportUnboundVariable** [boolean or string, optional]: Generate or suppress diagnostics for unbound and possibly unbound variables. The default value for this setting is 'error'.
|
||||
|
||||
**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'.
|
||||
|
||||
|
||||
## Execution Environment Options
|
||||
Pyright allows multiple “execution environments” to be defined for different portions of your source tree. For example, a subtree may be designed to run with different import search paths or a different version of the python interpreter than the rest of the source base.
|
||||
|
@ -770,10 +770,87 @@ export class Checker extends ParseTreeWalker {
|
||||
}
|
||||
}
|
||||
|
||||
if (!reportedUnreachable && this._fileInfo.isStubFile) {
|
||||
this._validateStubStatement(statement);
|
||||
}
|
||||
|
||||
this.walk(statement);
|
||||
}
|
||||
}
|
||||
|
||||
private _validateStubStatement(statement: StatementNode) {
|
||||
switch (statement.nodeType) {
|
||||
case ParseNodeType.If:
|
||||
case ParseNodeType.Function:
|
||||
case ParseNodeType.Class:
|
||||
case ParseNodeType.Error: {
|
||||
// These are allowed in a stub file.
|
||||
break;
|
||||
}
|
||||
|
||||
case ParseNodeType.While:
|
||||
case ParseNodeType.For:
|
||||
case ParseNodeType.Try:
|
||||
case ParseNodeType.With: {
|
||||
// These are not allowed.
|
||||
this._evaluator.addDiagnostic(
|
||||
this._fileInfo.diagnosticRuleSet.reportInvalidStubStatement,
|
||||
DiagnosticRule.reportInvalidStubStatement,
|
||||
Localizer.Diagnostic.invalidStubStatement(),
|
||||
statement
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ParseNodeType.StatementList: {
|
||||
for (const substatement of statement.statements) {
|
||||
switch (substatement.nodeType) {
|
||||
case ParseNodeType.Assert:
|
||||
case ParseNodeType.AssignmentExpression:
|
||||
case ParseNodeType.AugmentedAssignment:
|
||||
case ParseNodeType.Await:
|
||||
case ParseNodeType.BinaryOperation:
|
||||
case ParseNodeType.Call:
|
||||
case ParseNodeType.Constant:
|
||||
case ParseNodeType.Del:
|
||||
case ParseNodeType.Dictionary:
|
||||
case ParseNodeType.Index:
|
||||
case ParseNodeType.For:
|
||||
case ParseNodeType.FormatString:
|
||||
case ParseNodeType.Global:
|
||||
case ParseNodeType.Lambda:
|
||||
case ParseNodeType.List:
|
||||
case ParseNodeType.MemberAccess:
|
||||
case ParseNodeType.Name:
|
||||
case ParseNodeType.Nonlocal:
|
||||
case ParseNodeType.Number:
|
||||
case ParseNodeType.Raise:
|
||||
case ParseNodeType.Return:
|
||||
case ParseNodeType.Set:
|
||||
case ParseNodeType.Slice:
|
||||
case ParseNodeType.Ternary:
|
||||
case ParseNodeType.Tuple:
|
||||
case ParseNodeType.Try:
|
||||
case ParseNodeType.UnaryOperation:
|
||||
case ParseNodeType.Unpack:
|
||||
case ParseNodeType.While:
|
||||
case ParseNodeType.With:
|
||||
case ParseNodeType.WithItem:
|
||||
case ParseNodeType.Yield:
|
||||
case ParseNodeType.YieldFrom: {
|
||||
this._evaluator.addDiagnostic(
|
||||
this._fileInfo.diagnosticRuleSet.reportInvalidStubStatement,
|
||||
DiagnosticRule.reportInvalidStubStatement,
|
||||
Localizer.Diagnostic.invalidStubStatement(),
|
||||
substatement
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _validateExceptionType(exceptionType: Type, errorNode: ParseNode) {
|
||||
const baseExceptionType = this._evaluator.getBuiltInType(errorNode, 'BaseException');
|
||||
const derivesFromBaseException = (classType: ClassType) => {
|
||||
|
@ -196,6 +196,10 @@ export interface DiagnosticRuleSet {
|
||||
|
||||
// Report usage of unbound or possibly unbound variables.
|
||||
reportUnboundVariable: DiagnosticLevel;
|
||||
|
||||
// Report statements that are syntactically correct but
|
||||
// have no semantic meaning within a type stub file.
|
||||
reportInvalidStubStatement: DiagnosticLevel;
|
||||
}
|
||||
|
||||
export function cloneDiagnosticRuleSet(diagSettings: DiagnosticRuleSet): DiagnosticRuleSet {
|
||||
@ -256,6 +260,7 @@ export function getDiagLevelDiagnosticRules() {
|
||||
DiagnosticRule.reportImplicitStringConcatenation,
|
||||
DiagnosticRule.reportUndefinedVariable,
|
||||
DiagnosticRule.reportUnboundVariable,
|
||||
DiagnosticRule.reportInvalidStubStatement,
|
||||
];
|
||||
}
|
||||
|
||||
@ -313,6 +318,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet {
|
||||
reportImplicitStringConcatenation: 'none',
|
||||
reportUnboundVariable: 'warning',
|
||||
reportUndefinedVariable: 'warning',
|
||||
reportInvalidStubStatement: 'none',
|
||||
};
|
||||
|
||||
return diagSettings;
|
||||
@ -366,6 +372,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet {
|
||||
reportImplicitStringConcatenation: 'none',
|
||||
reportUnboundVariable: 'error',
|
||||
reportUndefinedVariable: 'error',
|
||||
reportInvalidStubStatement: 'none',
|
||||
};
|
||||
|
||||
return diagSettings;
|
||||
@ -419,6 +426,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet {
|
||||
reportImplicitStringConcatenation: 'none',
|
||||
reportUnboundVariable: 'error',
|
||||
reportUndefinedVariable: 'error',
|
||||
reportInvalidStubStatement: 'error',
|
||||
};
|
||||
|
||||
return diagSettings;
|
||||
@ -975,6 +983,13 @@ export class ConfigOptions {
|
||||
DiagnosticRule.reportUnboundVariable,
|
||||
defaultSettings.reportUnboundVariable
|
||||
),
|
||||
|
||||
// Read the "reportInvalidStubStatement" entry.
|
||||
reportInvalidStubStatement: this._convertDiagnosticLevel(
|
||||
configObj.reportInvalidStubStatement,
|
||||
DiagnosticRule.reportInvalidStubStatement,
|
||||
defaultSettings.reportInvalidStubStatement
|
||||
),
|
||||
};
|
||||
|
||||
// Read the "venvPath".
|
||||
|
@ -52,4 +52,5 @@ export const enum DiagnosticRule {
|
||||
reportImplicitStringConcatenation = 'reportImplicitStringConcatenation',
|
||||
reportUndefinedVariable = 'reportUndefinedVariable',
|
||||
reportUnboundVariable = 'reportUnboundVariable',
|
||||
reportInvalidStubStatement = 'reportInvalidStubStatement',
|
||||
}
|
||||
|
@ -329,6 +329,7 @@ export namespace Localizer {
|
||||
export const initSubclassClsParam = () => getRawString('Diagnostic.initSubclassClsParam');
|
||||
export const instanceMethodSelfParam = () => getRawString('Diagnostic.instanceMethodSelfParam');
|
||||
export const invalidIdentifierChar = () => getRawString('Diagnostic.invalidIdentifierChar');
|
||||
export const invalidStubStatement = () => getRawString('Diagnostic.invalidStubStatement');
|
||||
export const invalidTokenChars = () =>
|
||||
new ParameterizedString<{ text: string }>(getRawString('Diagnostic.invalidTokenChars'));
|
||||
export const isInstanceInvalidType = () =>
|
||||
|
@ -136,6 +136,7 @@
|
||||
"initSubclassClsParam": "__init_subclass__ override should take a \"cls\" parameter",
|
||||
"instanceMethodSelfParam": "Instance methods should take a \"self\" parameter",
|
||||
"invalidIdentifierChar": "Invalid character in identifier",
|
||||
"invalidStubStatement": "Statement is meaningless within a type stub file",
|
||||
"invalidTokenChars": "Invalid character in token \"{text}\"",
|
||||
"isInstanceInvalidType": "Second argument to \"isinstance\" must be a class or tuple of classes",
|
||||
"isSubclassInvalidType": "Second argument to \"issubclass\" must be a class or tuple of classes",
|
||||
|
Loading…
Reference in New Issue
Block a user