mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Added support for new reportTypeCommentUsage
diagnostic check. It flag the usage of # type: xxx
comments for functions and variables. These are still supported for backward compatibility, but they are increasingly irrelevant and will likely be deprecated in the next few years.
This commit is contained in:
parent
c5153a557c
commit
484faf7ba3
@ -104,6 +104,8 @@ The following settings control pyright’s diagnostic output (warnings or errors
|
||||
|
||||
**reportPrivateUsage** [boolean or string, optional]: Generate or suppress diagnostics for incorrect usage of private or protected variables or functions. Protected class members begin with a single underscore (“_”) and can be accessed only by subclasses. Private class members begin with a double underscore but do not end in a double underscore and can be accessed only within the declaring class. Variables and functions declared outside of a class are considered private if their names start with either a single or double underscore, and they cannot be accessed outside of the declaring module. The default value for this setting is 'none'.
|
||||
|
||||
**reportTypeCommentUsage** [boolean or string, optional]: Prior to Python 3.5, the grammar did not support type annotations, so types needed to be specified using “type comments”. Python 3.5 eliminated the need for function type comments, and Python 3.6 eliminated the need for variable type comments. Future versions of Python will likely deprecate all support for type comments. If enabled, this check will flag any type comment usage unless it is required for compatibility with the specified language version. The default value for this setting is 'none'.
|
||||
|
||||
**reportPrivateImportUsage** [boolean or string, optional]: Generate or suppress diagnostics for use of a symbol from a "py.typed" module that is not meant to be exported from that module. The default value for this setting is 'error'.
|
||||
|
||||
**reportConstantRedefinition** [boolean or string, optional]: Generate or suppress diagnostics for attempts to redefine variables whose names are all-caps with underscores and numerals. The default value for this setting is 'none'.
|
||||
@ -326,6 +328,7 @@ The following table lists the default severity levels for each diagnostic rule w
|
||||
| reportMissingTypeArgument | "none" | "none" | "error" |
|
||||
| reportOverlappingOverload | "none" | "none" | "error" |
|
||||
| reportPrivateUsage | "none" | "none" | "error" |
|
||||
| reportTypeCommentUsage | "none" | "none" | "error" |
|
||||
| reportUnknownArgumentType | "none" | "none" | "error" |
|
||||
| reportUnknownLambdaType | "none" | "none" | "error" |
|
||||
| reportUnknownMemberType | "none" | "none" | "error" |
|
||||
|
@ -562,6 +562,18 @@ export class Checker extends ParseTreeWalker {
|
||||
|
||||
if (node.functionAnnotationComment) {
|
||||
this.walk(node.functionAnnotationComment);
|
||||
|
||||
if (
|
||||
this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage !== 'none' &&
|
||||
this._fileInfo.executionEnvironment.pythonVersion >= PythonVersion.V3_5
|
||||
) {
|
||||
this._evaluator.addDiagnostic(
|
||||
this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage,
|
||||
DiagnosticRule.reportTypeCommentUsage,
|
||||
Localizer.Diagnostic.typeCommentDeprecated(),
|
||||
node.functionAnnotationComment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.walkMultiple(node.decorators);
|
||||
@ -1055,6 +1067,18 @@ export class Checker extends ParseTreeWalker {
|
||||
this._evaluator.evaluateTypesForStatement(node);
|
||||
if (node.typeAnnotationComment) {
|
||||
this._evaluator.getType(node.typeAnnotationComment);
|
||||
|
||||
if (
|
||||
this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage !== 'none' &&
|
||||
this._fileInfo.executionEnvironment.pythonVersion >= PythonVersion.V3_6
|
||||
) {
|
||||
this._evaluator.addDiagnostic(
|
||||
this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage,
|
||||
DiagnosticRule.reportTypeCommentUsage,
|
||||
Localizer.Diagnostic.typeCommentDeprecated(),
|
||||
node.typeAnnotationComment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -174,6 +174,9 @@ export interface DiagnosticRuleSet {
|
||||
// the owning class or module?
|
||||
reportPrivateUsage: DiagnosticLevel;
|
||||
|
||||
// Report usage of deprecated type comments.
|
||||
reportTypeCommentUsage: DiagnosticLevel;
|
||||
|
||||
// Report usage of an import from a py.typed module that is
|
||||
// not meant to be re-exported from that module.
|
||||
reportPrivateImportUsage: DiagnosticLevel;
|
||||
@ -345,6 +348,7 @@ export function getDiagLevelDiagnosticRules() {
|
||||
DiagnosticRule.reportUntypedBaseClass,
|
||||
DiagnosticRule.reportUntypedNamedTuple,
|
||||
DiagnosticRule.reportPrivateUsage,
|
||||
DiagnosticRule.reportTypeCommentUsage,
|
||||
DiagnosticRule.reportPrivateImportUsage,
|
||||
DiagnosticRule.reportConstantRedefinition,
|
||||
DiagnosticRule.reportIncompatibleMethodOverride,
|
||||
@ -425,6 +429,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet {
|
||||
reportUntypedBaseClass: 'none',
|
||||
reportUntypedNamedTuple: 'none',
|
||||
reportPrivateUsage: 'none',
|
||||
reportTypeCommentUsage: 'none',
|
||||
reportPrivateImportUsage: 'none',
|
||||
reportConstantRedefinition: 'none',
|
||||
reportIncompatibleMethodOverride: 'none',
|
||||
@ -501,6 +506,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet {
|
||||
reportUntypedBaseClass: 'none',
|
||||
reportUntypedNamedTuple: 'none',
|
||||
reportPrivateUsage: 'none',
|
||||
reportTypeCommentUsage: 'none',
|
||||
reportPrivateImportUsage: 'error',
|
||||
reportConstantRedefinition: 'none',
|
||||
reportIncompatibleMethodOverride: 'none',
|
||||
@ -577,6 +583,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet {
|
||||
reportUntypedBaseClass: 'error',
|
||||
reportUntypedNamedTuple: 'error',
|
||||
reportPrivateUsage: 'error',
|
||||
reportTypeCommentUsage: 'error',
|
||||
reportPrivateImportUsage: 'error',
|
||||
reportConstantRedefinition: 'error',
|
||||
reportIncompatibleMethodOverride: 'error',
|
||||
|
@ -42,6 +42,7 @@ export enum DiagnosticRule {
|
||||
reportUntypedBaseClass = 'reportUntypedBaseClass',
|
||||
reportUntypedNamedTuple = 'reportUntypedNamedTuple',
|
||||
reportPrivateUsage = 'reportPrivateUsage',
|
||||
reportTypeCommentUsage = 'reportTypeCommentUsage',
|
||||
reportPrivateImportUsage = 'reportPrivateImportUsage',
|
||||
reportConstantRedefinition = 'reportConstantRedefinition',
|
||||
reportIncompatibleMethodOverride = 'reportIncompatibleMethodOverride',
|
||||
|
@ -789,6 +789,7 @@ export namespace Localizer {
|
||||
getRawString('Diagnostic.typeAssignmentMismatch')
|
||||
);
|
||||
export const typeCallNotAllowed = () => getRawString('Diagnostic.typeCallNotAllowed');
|
||||
export const typeCommentDeprecated = () => getRawString('Diagnostic.typeCommentDeprecated');
|
||||
export const typedDictAccess = () => getRawString('Diagnostic.typedDictAccess');
|
||||
export const typedDictBadVar = () => getRawString('Diagnostic.typedDictBadVar');
|
||||
export const typedDictBaseClass = () => getRawString('Diagnostic.typedDictBaseClass');
|
||||
|
@ -390,6 +390,7 @@
|
||||
"typeArgsTooMany": "Too many type arguments provided for \"{name}\"; expected {expected} but received {received}",
|
||||
"typeAssignmentMismatch": "Expression of type \"{sourceType}\" cannot be assigned to declared type \"{destType}\"",
|
||||
"typeCallNotAllowed": "type() call should not be used in type annotation",
|
||||
"typeCommentDeprecated": "Use of type comments is deprecated; use type annotation instead",
|
||||
"typedDictAccess": "Could not access item in TypedDict",
|
||||
"typedDictBadVar": "TypedDict classes can contain only type annotations",
|
||||
"typedDictBaseClass": "All base classes for TypedDict classes must also be TypedDict classes",
|
||||
|
13
packages/pyright-internal/src/tests/samples/annotatedVar7.py
Normal file
13
packages/pyright-internal/src/tests/samples/annotatedVar7.py
Normal file
@ -0,0 +1,13 @@
|
||||
# This sample tests the reportTypeCommentUsage diagnostic check.
|
||||
|
||||
# This should generate an error if reportTypeCommentUsage is enabled.
|
||||
x = 3 # type: int
|
||||
|
||||
|
||||
class Foo:
|
||||
# This should generate an error if reportTypeCommentUsage is enabled.
|
||||
y = 0 # type: int
|
||||
|
||||
def __init__(self):
|
||||
# This should generate an error if reportTypeCommentUsage is enabled.
|
||||
self.x = 2 # type: int
|
@ -1,6 +1,6 @@
|
||||
# This sample tests support for comment-style function annotations.
|
||||
|
||||
# pyright: strict, reportMissingParameterType=false
|
||||
# pyright: strict, reportMissingParameterType=false, reportTypeCommentUsage=false
|
||||
|
||||
from typing import Optional, Literal as _Literal, Union
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
# This sample tests the reportTypeCommentUsage diagnostic check.
|
||||
|
||||
from typing import Optional
|
||||
|
||||
# This should generate an error if reportTypeCommentUsage is enabled.
|
||||
def func1a(a, b):
|
||||
# type: (int, str) -> str
|
||||
return ""
|
||||
|
||||
|
||||
# This should generate an error if reportTypeCommentUsage is enabled.
|
||||
def func1b(a, b): # type: (Optional[str], int) -> str
|
||||
return ""
|
||||
|
||||
|
||||
# This should generate an error if reportTypeCommentUsage is enabled.
|
||||
def func1c(
|
||||
a, # type: int
|
||||
b, # type: str
|
||||
):
|
||||
# type: (...) -> str
|
||||
return ""
|
@ -800,6 +800,17 @@ test('AnnotatedVar6', () => {
|
||||
TestUtils.validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('AnnotatedVar7', () => {
|
||||
const configOptions = new ConfigOptions('.');
|
||||
|
||||
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['annotatedVar7.py'], configOptions);
|
||||
TestUtils.validateResults(analysisResults1, 0);
|
||||
|
||||
configOptions.diagnosticRuleSet.reportTypeCommentUsage = 'error';
|
||||
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['annotatedVar7.py'], configOptions);
|
||||
TestUtils.validateResults(analysisResults2, 3);
|
||||
});
|
||||
|
||||
test('CodeFlow1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['codeFlow1.py']);
|
||||
|
||||
|
@ -1159,6 +1159,17 @@ test('FunctionAnnotation3', () => {
|
||||
TestUtils.validateResults(analysisResults, 2);
|
||||
});
|
||||
|
||||
test('FunctionAnnotation4', () => {
|
||||
const configOptions = new ConfigOptions('.');
|
||||
|
||||
const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['functionAnnotation4.py'], configOptions);
|
||||
TestUtils.validateResults(analysisResults1, 0);
|
||||
|
||||
configOptions.diagnosticRuleSet.reportTypeCommentUsage = 'error';
|
||||
const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['functionAnnotation4.py'], configOptions);
|
||||
TestUtils.validateResults(analysisResults2, 3);
|
||||
});
|
||||
|
||||
test('Subscript1', () => {
|
||||
const configOptions = new ConfigOptions('.');
|
||||
|
||||
|
@ -388,6 +388,17 @@
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"reportTypeCommentUsage": {
|
||||
"type": "string",
|
||||
"description": "Diagnostics for usage of deprecated type comments.",
|
||||
"default": "none",
|
||||
"enum": [
|
||||
"none",
|
||||
"information",
|
||||
"warning",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"reportPrivateImportUsage": {
|
||||
"type": "string",
|
||||
"description": "Diagnostics for incorrect usage of symbol imported from a \"py.typed\" module that is not re-exported from that module.",
|
||||
|
@ -292,6 +292,12 @@
|
||||
"title": "Controls reporting of private variables and functions used outside of the owning class or module and usage of protected members outside of subclasses",
|
||||
"default": "none"
|
||||
},
|
||||
"reportTypeCommentUsage": {
|
||||
"$id": "#/properties/reportTypeCommentUsage",
|
||||
"$ref": "#/definitions/diagnostic",
|
||||
"title": "Controls reporting of deprecated type comment usage",
|
||||
"default": "none"
|
||||
},
|
||||
"reportPrivateImportUsage": {
|
||||
"$id": "#/properties/reportPrivateImportUsage",
|
||||
"$ref": "#/definitions/diagnostic",
|
||||
|
Loading…
Reference in New Issue
Block a user