mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-26 10:55:06 +03:00
Added new diagnostic check reportUnusedExpression
to catch bugs like a == 4
when a = 4
was intended.
This commit is contained in:
parent
1a61f7328f
commit
d28c481535
@ -164,6 +164,8 @@ The following settings control pyright’s diagnostic output (warnings or errors
|
|||||||
|
|
||||||
**reportUnusedCoroutine** [boolean or string, optional]: Generate or suppress diagnostics for call statements whose return value is not used in any way and is a Coroutine. This identifies a common error where an `await` keyword is mistakenly omitted. The default value for this setting is 'error'.
|
**reportUnusedCoroutine** [boolean or string, optional]: Generate or suppress diagnostics for call statements whose return value is not used in any way and is a Coroutine. This identifies a common error where an `await` keyword is mistakenly omitted. The default value for this setting is 'error'.
|
||||||
|
|
||||||
|
**reportUnusedExpression** [boolean or string, optional]: Generate or suppress diagnostics for simple expressions whose results are not used in any way. The default value for this setting is 'none'.
|
||||||
|
|
||||||
**reportUnnecessaryTypeIgnoreComment** [boolean or string, optional]: Generate or suppress diagnostics for a '# type: ignore' or '# pyright: ignore' comment that would have no effect if removed. The default value for this setting is 'none'.
|
**reportUnnecessaryTypeIgnoreComment** [boolean or string, optional]: Generate or suppress diagnostics for a '# type: ignore' or '# pyright: ignore' comment that would have no effect if removed. The default value for this setting is 'none'.
|
||||||
|
|
||||||
**reportMatchNotExhaustive** [boolean or string, optional]: Generate or suppress diagnostics for a 'match' statement that does not provide cases that exhaustively match against all potential types of the target expression. The default value for this setting is 'none'.
|
**reportMatchNotExhaustive** [boolean or string, optional]: Generate or suppress diagnostics for a 'match' statement that does not provide cases that exhaustively match against all potential types of the target expression. The default value for this setting is 'none'.
|
||||||
@ -337,6 +339,7 @@ The following table lists the default severity levels for each diagnostic rule w
|
|||||||
| reportUnsupportedDunderAll | "none" | "warning" | "error" |
|
| reportUnsupportedDunderAll | "none" | "warning" | "error" |
|
||||||
| reportUnusedCallResult | "none" | "none" | "none" |
|
| reportUnusedCallResult | "none" | "none" | "none" |
|
||||||
| reportUnusedCoroutine | "none" | "error" | "error" |
|
| reportUnusedCoroutine | "none" | "error" | "error" |
|
||||||
|
| reportUnusedExpression | "none" | "warning" | "error" |
|
||||||
| reportUnnecessaryTypeIgnoreComment | "none" | "none" | "none" |
|
| reportUnnecessaryTypeIgnoreComment | "none" | "none" | "none" |
|
||||||
| reportMatchNotExhaustive | "none" | "none" | "error" |
|
| reportMatchNotExhaustive | "none" | "none" | "error" |
|
||||||
|
|
||||||
|
@ -267,6 +267,8 @@ export class Checker extends ParseTreeWalker {
|
|||||||
// through lazy analysis. This will mark referenced symbols as
|
// through lazy analysis. This will mark referenced symbols as
|
||||||
// accessed and report any errors associated with it.
|
// accessed and report any errors associated with it.
|
||||||
this._evaluator.getType(statement);
|
this._evaluator.getType(statement);
|
||||||
|
|
||||||
|
this._reportUnusedExpression(statement);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1317,6 +1319,28 @@ export class Checker extends ParseTreeWalker {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _reportUnusedExpression(node: ParseNode) {
|
||||||
|
if (this._fileInfo.diagnosticRuleSet.reportUnusedExpression === 'none') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const simpleExpressionTypes = [
|
||||||
|
ParseNodeType.UnaryOperation,
|
||||||
|
ParseNodeType.BinaryOperation,
|
||||||
|
ParseNodeType.Number,
|
||||||
|
ParseNodeType.Constant
|
||||||
|
];
|
||||||
|
|
||||||
|
if (simpleExpressionTypes.some((nodeType) => nodeType === node.nodeType)) {
|
||||||
|
this._evaluator.addDiagnostic(
|
||||||
|
this._fileInfo.diagnosticRuleSet.reportUnusedExpression,
|
||||||
|
DiagnosticRule.reportUnusedExpression,
|
||||||
|
Localizer.Diagnostic.unusedExpression(),
|
||||||
|
node
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _validateExhaustiveMatch(node: MatchNode) {
|
private _validateExhaustiveMatch(node: MatchNode) {
|
||||||
// This check can be expensive, so skip it if it's disabled.
|
// This check can be expensive, so skip it if it's disabled.
|
||||||
if (this._fileInfo.diagnosticRuleSet.reportMatchNotExhaustive === 'none') {
|
if (this._fileInfo.diagnosticRuleSet.reportMatchNotExhaustive === 'none') {
|
||||||
|
@ -279,6 +279,9 @@ export interface DiagnosticRuleSet {
|
|||||||
// and is not used in any way.
|
// and is not used in any way.
|
||||||
reportUnusedCoroutine: DiagnosticLevel;
|
reportUnusedCoroutine: DiagnosticLevel;
|
||||||
|
|
||||||
|
// Report cases where a simple expression result is not used in any way.
|
||||||
|
reportUnusedExpression: DiagnosticLevel;
|
||||||
|
|
||||||
// Report cases where the removal of a "# type: ignore" or "# pyright: ignore"
|
// Report cases where the removal of a "# type: ignore" or "# pyright: ignore"
|
||||||
// comment would have no effect.
|
// comment would have no effect.
|
||||||
reportUnnecessaryTypeIgnoreComment: DiagnosticLevel;
|
reportUnnecessaryTypeIgnoreComment: DiagnosticLevel;
|
||||||
@ -373,6 +376,7 @@ export function getDiagLevelDiagnosticRules() {
|
|||||||
DiagnosticRule.reportUnsupportedDunderAll,
|
DiagnosticRule.reportUnsupportedDunderAll,
|
||||||
DiagnosticRule.reportUnusedCallResult,
|
DiagnosticRule.reportUnusedCallResult,
|
||||||
DiagnosticRule.reportUnusedCoroutine,
|
DiagnosticRule.reportUnusedCoroutine,
|
||||||
|
DiagnosticRule.reportUnusedExpression,
|
||||||
DiagnosticRule.reportUnnecessaryTypeIgnoreComment,
|
DiagnosticRule.reportUnnecessaryTypeIgnoreComment,
|
||||||
DiagnosticRule.reportMatchNotExhaustive,
|
DiagnosticRule.reportMatchNotExhaustive,
|
||||||
];
|
];
|
||||||
@ -452,6 +456,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet {
|
|||||||
reportUnsupportedDunderAll: 'none',
|
reportUnsupportedDunderAll: 'none',
|
||||||
reportUnusedCallResult: 'none',
|
reportUnusedCallResult: 'none',
|
||||||
reportUnusedCoroutine: 'none',
|
reportUnusedCoroutine: 'none',
|
||||||
|
reportUnusedExpression: 'none',
|
||||||
reportUnnecessaryTypeIgnoreComment: 'none',
|
reportUnnecessaryTypeIgnoreComment: 'none',
|
||||||
reportMatchNotExhaustive: 'none',
|
reportMatchNotExhaustive: 'none',
|
||||||
};
|
};
|
||||||
@ -527,6 +532,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet {
|
|||||||
reportUnsupportedDunderAll: 'warning',
|
reportUnsupportedDunderAll: 'warning',
|
||||||
reportUnusedCallResult: 'none',
|
reportUnusedCallResult: 'none',
|
||||||
reportUnusedCoroutine: 'error',
|
reportUnusedCoroutine: 'error',
|
||||||
|
reportUnusedExpression: 'warning',
|
||||||
reportUnnecessaryTypeIgnoreComment: 'none',
|
reportUnnecessaryTypeIgnoreComment: 'none',
|
||||||
reportMatchNotExhaustive: 'none',
|
reportMatchNotExhaustive: 'none',
|
||||||
};
|
};
|
||||||
@ -602,6 +608,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet {
|
|||||||
reportUnsupportedDunderAll: 'error',
|
reportUnsupportedDunderAll: 'error',
|
||||||
reportUnusedCallResult: 'none',
|
reportUnusedCallResult: 'none',
|
||||||
reportUnusedCoroutine: 'error',
|
reportUnusedCoroutine: 'error',
|
||||||
|
reportUnusedExpression: 'error',
|
||||||
reportUnnecessaryTypeIgnoreComment: 'none',
|
reportUnnecessaryTypeIgnoreComment: 'none',
|
||||||
reportMatchNotExhaustive: 'error',
|
reportMatchNotExhaustive: 'error',
|
||||||
};
|
};
|
||||||
|
@ -73,6 +73,7 @@ export enum DiagnosticRule {
|
|||||||
reportUnsupportedDunderAll = 'reportUnsupportedDunderAll',
|
reportUnsupportedDunderAll = 'reportUnsupportedDunderAll',
|
||||||
reportUnusedCallResult = 'reportUnusedCallResult',
|
reportUnusedCallResult = 'reportUnusedCallResult',
|
||||||
reportUnusedCoroutine = 'reportUnusedCoroutine',
|
reportUnusedCoroutine = 'reportUnusedCoroutine',
|
||||||
|
reportUnusedExpression = 'reportUnusedExpression',
|
||||||
reportUnnecessaryTypeIgnoreComment = 'reportUnnecessaryTypeIgnoreComment',
|
reportUnnecessaryTypeIgnoreComment = 'reportUnnecessaryTypeIgnoreComment',
|
||||||
reportMatchNotExhaustive = 'reportMatchNotExhaustive',
|
reportMatchNotExhaustive = 'reportMatchNotExhaustive',
|
||||||
}
|
}
|
||||||
|
@ -914,6 +914,7 @@ export namespace Localizer {
|
|||||||
export const unusedCallResult = () =>
|
export const unusedCallResult = () =>
|
||||||
new ParameterizedString<{ type: string }>(getRawString('Diagnostic.unusedCallResult'));
|
new ParameterizedString<{ type: string }>(getRawString('Diagnostic.unusedCallResult'));
|
||||||
export const unusedCoroutine = () => getRawString('Diagnostic.unusedCoroutine');
|
export const unusedCoroutine = () => getRawString('Diagnostic.unusedCoroutine');
|
||||||
|
export const unusedExpression = () => getRawString('Diagnostic.unusedExpression');
|
||||||
export const varAnnotationIllegal = () => getRawString('Diagnostic.varAnnotationIllegal');
|
export const varAnnotationIllegal = () => getRawString('Diagnostic.varAnnotationIllegal');
|
||||||
export const variadicTypeArgsTooMany = () => getRawString('Diagnostic.variadicTypeArgsTooMany');
|
export const variadicTypeArgsTooMany = () => getRawString('Diagnostic.variadicTypeArgsTooMany');
|
||||||
export const variadicTypeParamTooManyAlias = () =>
|
export const variadicTypeParamTooManyAlias = () =>
|
||||||
|
@ -468,6 +468,7 @@
|
|||||||
"unsupportedDunderAllOperation": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
|
"unsupportedDunderAllOperation": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
|
||||||
"unusedCallResult": "Result of call expression is of type \"{type}\" and is not used; assign to variable \"_\" if this is intentional",
|
"unusedCallResult": "Result of call expression is of type \"{type}\" and is not used; assign to variable \"_\" if this is intentional",
|
||||||
"unusedCoroutine": "Result of async function call is not used; use \"await\" or assign result to variable",
|
"unusedCoroutine": "Result of async function call is not used; use \"await\" or assign result to variable",
|
||||||
|
"unusedExpression": "Expression value is unused",
|
||||||
"varAnnotationIllegal": "Type annotations for variables requires Python 3.6 or newer; use type comment for compatibility with previous versions",
|
"varAnnotationIllegal": "Type annotations for variables requires Python 3.6 or newer; use type comment for compatibility with previous versions",
|
||||||
"variadicTypeArgsTooMany": "Type argument list can have at most one unpacked TypeVarTuple or Tuple",
|
"variadicTypeArgsTooMany": "Type argument list can have at most one unpacked TypeVarTuple or Tuple",
|
||||||
"variadicTypeParamTooManyAlias": "Type alias can have at most one TypeVarTuple type parameter but received multiple ({names})",
|
"variadicTypeParamTooManyAlias": "Type alias can have at most one TypeVarTuple type parameter but received multiple ({names})",
|
||||||
|
@ -396,6 +396,24 @@ test('Strings1', () => {
|
|||||||
TestUtils.validateResults(analysisResults2, 2);
|
TestUtils.validateResults(analysisResults2, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('UnusedExpression1', () => {
|
||||||
|
const configOptions = new ConfigOptions('.');
|
||||||
|
|
||||||
|
// By default, this is a warning.
|
||||||
|
let analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedExpression1.py'], configOptions);
|
||||||
|
TestUtils.validateResults(analysisResults, 0, 9);
|
||||||
|
|
||||||
|
// Disable it.
|
||||||
|
configOptions.diagnosticRuleSet.reportUnusedExpression = 'none';
|
||||||
|
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedExpression1.py'], configOptions);
|
||||||
|
TestUtils.validateResults(analysisResults, 0);
|
||||||
|
|
||||||
|
// Enable it as an error.
|
||||||
|
configOptions.diagnosticRuleSet.reportUnusedExpression = 'error';
|
||||||
|
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unusedExpression1.py'], configOptions);
|
||||||
|
TestUtils.validateResults(analysisResults, 9);
|
||||||
|
});
|
||||||
|
|
||||||
// For now, this functionality is disabled.
|
// For now, this functionality is disabled.
|
||||||
|
|
||||||
// test('Deprecated1', () => {
|
// test('Deprecated1', () => {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# This sample tests the Python 3.8 assignment expressions.
|
# This sample tests the Python 3.8 assignment expressions.
|
||||||
|
|
||||||
|
# pyright: reportUnusedExpression=false
|
||||||
|
|
||||||
def func1():
|
def func1():
|
||||||
b = 'a'
|
b = 'a'
|
||||||
d = 'b'
|
d = 'b'
|
||||||
|
@ -40,7 +40,7 @@ def func2(v1: Optional[int]):
|
|||||||
if v1 is not None:
|
if v1 is not None:
|
||||||
|
|
||||||
def func2_inner1():
|
def func2_inner1():
|
||||||
v1 + 5
|
x = v1 + 5
|
||||||
|
|
||||||
def func2_inner2():
|
def func2_inner2():
|
||||||
lambda: v1 + 5
|
lambda: v1 + 5
|
||||||
|
@ -33,7 +33,7 @@ d4 = DataTuple(id=1, aid=Other(), name=None)
|
|||||||
id = d1.id
|
id = d1.id
|
||||||
|
|
||||||
h4: Hashable = d4
|
h4: Hashable = d4
|
||||||
d3 == d4
|
v = d3 == d4
|
||||||
|
|
||||||
# This should generate an error because the name argument
|
# This should generate an error because the name argument
|
||||||
# is the incorrect type.
|
# is the incorrect type.
|
||||||
|
@ -37,7 +37,7 @@ def func1(obj: A) -> Literal[3]:
|
|||||||
|
|
||||||
obj.prop1 = 3
|
obj.prop1 = 3
|
||||||
|
|
||||||
obj.prop1 + 1
|
v1 = obj.prop1 + 1
|
||||||
return obj.prop1
|
return obj.prop1
|
||||||
|
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ def func4(obj: B) -> Literal[3]:
|
|||||||
|
|
||||||
obj.desc1 = 3
|
obj.desc1 = 3
|
||||||
|
|
||||||
obj.desc1 + 1
|
v1 = obj.desc1 + 1
|
||||||
return obj.desc1
|
return obj.desc1
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,4 +21,4 @@ def func2(a: _T) -> bool | _T:
|
|||||||
|
|
||||||
y = func2(None)
|
y = func2(None)
|
||||||
if y is not True:
|
if y is not True:
|
||||||
y or func2(False)
|
z = y or func2(False)
|
||||||
|
@ -8,4 +8,4 @@ import unresolved_import
|
|||||||
|
|
||||||
def test_zero_division():
|
def test_zero_division():
|
||||||
with unresolved_import.raises(ZeroDivisionError):
|
with unresolved_import.raises(ZeroDivisionError):
|
||||||
1 / 0
|
v = 1 / 0
|
||||||
|
@ -28,6 +28,6 @@ def func1(a: Foo):
|
|||||||
reveal_type(type(a) == Foo, expected_text="str")
|
reveal_type(type(a) == Foo, expected_text="str")
|
||||||
|
|
||||||
# This should generate an error
|
# This should generate an error
|
||||||
str + str
|
x = str + str
|
||||||
|
|
||||||
reveal_type(Foo + Foo, expected_text="int")
|
reveal_type(Foo + Foo, expected_text="int")
|
||||||
|
@ -18,5 +18,5 @@ class B:
|
|||||||
|
|
||||||
a, b = A(), B()
|
a, b = A(), B()
|
||||||
|
|
||||||
a @ b
|
v1 = a @ b
|
||||||
b @ a
|
v2 = b @ a
|
||||||
|
@ -72,6 +72,6 @@ e = None
|
|||||||
if 1:
|
if 1:
|
||||||
e = 4
|
e = 4
|
||||||
|
|
||||||
e + 4
|
v1 = e + 4
|
||||||
e < 5
|
v2 = e < 5
|
||||||
not e
|
v3 = not e
|
||||||
|
@ -6,19 +6,19 @@ from typing import Optional
|
|||||||
|
|
||||||
def foo(self, x: Optional[int]) -> str:
|
def foo(self, x: Optional[int]) -> str:
|
||||||
# This should suppress the error
|
# This should suppress the error
|
||||||
x + "hi" # pyright: ignore - test
|
v1 = x + "hi" # pyright: ignore - test
|
||||||
|
|
||||||
# This is unnecessary
|
# This is unnecessary
|
||||||
x + x # pyright: ignore
|
v2 = x + x # pyright: ignore
|
||||||
|
|
||||||
# This will not suppress the error
|
# This will not suppress the error
|
||||||
# These are both unnecessary
|
# These are both unnecessary
|
||||||
x + x # pyright: ignore [foo, bar]
|
v3 = x + x # pyright: ignore [foo, bar]
|
||||||
|
|
||||||
# This will not suppress the error
|
# This will not suppress the error
|
||||||
x + x # pyright: ignore []
|
v4 = x + x # pyright: ignore []
|
||||||
|
|
||||||
# One of these is unnecessary
|
# One of these is unnecessary
|
||||||
x + "hi" # pyright: ignore [reportGeneralTypeIssues, foo]
|
v5 = x + "hi" # pyright: ignore [reportGeneralTypeIssues, foo]
|
||||||
|
|
||||||
return 3 # pyright: ignore [reportGeneralTypeIssues]
|
return 3 # pyright: ignore [reportGeneralTypeIssues]
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
# errors, but it should exhibit good recovery, preferably
|
# errors, but it should exhibit good recovery, preferably
|
||||||
# emitting one error per instance, not a cascade of errors.
|
# emitting one error per instance, not a cascade of errors.
|
||||||
|
|
||||||
|
# pyright: reportUnusedExpression=false
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
print 3 + 3
|
print 3 + 3
|
||||||
|
|
||||||
|
@ -13,12 +13,12 @@ class ClassA:
|
|||||||
|
|
||||||
a = ClassA()
|
a = ClassA()
|
||||||
b = ClassA()
|
b = ClassA()
|
||||||
a < b
|
v1 = a < b
|
||||||
a <= b
|
v2 = a <= b
|
||||||
a > b
|
v3 = a > b
|
||||||
a >= b
|
v4 = a >= b
|
||||||
a == b
|
v5 = a == b
|
||||||
a != b
|
v6 = a != b
|
||||||
|
|
||||||
# This should generate an error because it doesn't declare
|
# This should generate an error because it doesn't declare
|
||||||
# any of the required ordering functions.
|
# any of the required ordering functions.
|
||||||
|
@ -7,6 +7,6 @@ exc: Type[Exception] = Exception
|
|||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
1 / 0
|
v = 1 / 0
|
||||||
except exc:
|
except exc:
|
||||||
print("exc")
|
print("exc")
|
||||||
|
@ -5,17 +5,17 @@ from typing import Tuple
|
|||||||
|
|
||||||
|
|
||||||
def func1(t1: Tuple[int, ...], t2: Tuple[int, ...]):
|
def func1(t1: Tuple[int, ...], t2: Tuple[int, ...]):
|
||||||
t1 >= t2
|
return t1 >= t2
|
||||||
|
|
||||||
|
|
||||||
def func2(t1: Tuple[int, ...], t2: Tuple[str, int]):
|
def func2(t1: Tuple[int, ...], t2: Tuple[str, int]):
|
||||||
t1 < t2
|
return t1 < t2
|
||||||
|
|
||||||
|
|
||||||
def func3(t1: Tuple[int, int], t2: Tuple[int, ...]):
|
def func3(t1: Tuple[int, int], t2: Tuple[int, ...]):
|
||||||
t1 > t2
|
return t1 > t2
|
||||||
|
|
||||||
|
|
||||||
def func4(t1: Tuple[int, ...], t2: Tuple[str, ...]):
|
def func4(t1: Tuple[int, ...], t2: Tuple[str, ...]):
|
||||||
# This should generate an error
|
# This should generate an error
|
||||||
t1 <= t2
|
return t1 <= t2
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
# This sample tests the reportUnusedExpression diagnostic rule.
|
||||||
|
|
||||||
|
t = 1
|
||||||
|
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
-4
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
4j
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
4j + 4
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
False
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
t == 1
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
t != 2
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
t <= t
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
not t
|
||||||
|
|
||||||
|
# This should generate a diagnostic.
|
||||||
|
None
|
@ -729,6 +729,17 @@
|
|||||||
"error"
|
"error"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"reportUnusedExpression": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Diagnostics for simple expressions whose value is not used in any way.",
|
||||||
|
"default": "warning",
|
||||||
|
"enum": [
|
||||||
|
"none",
|
||||||
|
"information",
|
||||||
|
"warning",
|
||||||
|
"error"
|
||||||
|
]
|
||||||
|
},
|
||||||
"reportUnnecessaryTypeIgnoreComment": {
|
"reportUnnecessaryTypeIgnoreComment": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Diagnostics for '# type: ignore' comments that have no effect.",
|
"description": "Diagnostics for '# type: ignore' comments that have no effect.",
|
||||||
|
@ -467,6 +467,12 @@
|
|||||||
"title": "Controls reporting of call expressions that returns Coroutine whose results are not consumed",
|
"title": "Controls reporting of call expressions that returns Coroutine whose results are not consumed",
|
||||||
"default": "error"
|
"default": "error"
|
||||||
},
|
},
|
||||||
|
"reportUnusedExpression": {
|
||||||
|
"$id": "#/properties/reportUnusedExpression",
|
||||||
|
"$ref": "#/definitions/diagnostic",
|
||||||
|
"title": "Controls reporting of simple expressions whose value is not used in any way",
|
||||||
|
"default": "warning"
|
||||||
|
},
|
||||||
"reportUnnecessaryTypeIgnoreComment": {
|
"reportUnnecessaryTypeIgnoreComment": {
|
||||||
"$id": "#/properties/reportUnnecessaryTypeIgnoreComment",
|
"$id": "#/properties/reportUnnecessaryTypeIgnoreComment",
|
||||||
"$ref": "#/definitions/diagnostic",
|
"$ref": "#/definitions/diagnostic",
|
||||||
|
Loading…
Reference in New Issue
Block a user