mirror of
https://github.com/microsoft/pyright.git
synced 2024-08-17 03:40:44 +03:00
Added "reportOptionalContextManager" config switch.
This commit is contained in:
parent
6ecc499de7
commit
9a08af039f
@ -109,6 +109,12 @@
|
||||
"title": "Controls reporting of attempts to use an Optional type as an iterable value",
|
||||
"default": "none"
|
||||
},
|
||||
"reportOptionalContextManager": {
|
||||
"$id": "#/properties/reportOptionalContextManager",
|
||||
"$ref": "#/definitions/diagnostic",
|
||||
"title": "Controls reporting of attempts to use an Optional type as a parameter to a with statement",
|
||||
"default": "none"
|
||||
},
|
||||
"reportUntypedFunctionDecorator": {
|
||||
"$id": "#/properties/reportUntypedFunctionDecorator",
|
||||
"$ref": "#/definitions/diagnostic",
|
||||
|
@ -44,6 +44,8 @@ The following settings control pyright's diagnostic output (warnings or errors).
|
||||
|
||||
**reportOptionalIterable** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to use an Optional type as an iterable value (e.g. within a `for` statement). The default value for this setting is 'none'.
|
||||
|
||||
**reportOptionalContextManager** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to use an Optional type as a context manager (as a parameter to a `with` statement). The default value for this setting is 'none'.
|
||||
|
||||
**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.
|
||||
|
||||
**reportUntypedClassDecorator** [boolean or string, optional]: Generate or suppress diagnostics for class decorators that have no type annotations. These obscure the class type, defeating many type analysis features.
|
||||
|
@ -623,7 +623,16 @@ export class TypeAnalyzer extends ParseTreeWalker {
|
||||
});
|
||||
|
||||
node.withItems.forEach(item => {
|
||||
const exprType = this._getTypeOfExpression(item.expression);
|
||||
let exprType = this._getTypeOfExpression(item.expression);
|
||||
|
||||
if (exprType instanceof UnionType && exprType.getTypes().some(t => t instanceof NoneType)) {
|
||||
this._addDiagnostic(
|
||||
this._fileInfo.configOptions.reportOptionalContextManager,
|
||||
`Object of type 'None' cannot be used with 'with'`,
|
||||
node);
|
||||
exprType = exprType.removeOptional();
|
||||
}
|
||||
|
||||
const enterMethodName = node.isAsync ? '__aenter__' : '__enter__';
|
||||
|
||||
const scopedType = TypeUtils.doForSubtypes(exprType, subtype => {
|
||||
|
@ -100,6 +100,9 @@ export class ConfigOptions {
|
||||
// Report attempts to use an Optional type as an iterable?
|
||||
reportOptionalIterable: DiagnosticLevel = 'none';
|
||||
|
||||
// Report attempts to use an Optional type in a "with" statement?
|
||||
reportOptionalContextManager: DiagnosticLevel = 'none';
|
||||
|
||||
// Report untyped function decorators that obscure the function type?
|
||||
reportUntypedFunctionDecorator: DiagnosticLevel = 'none';
|
||||
|
||||
@ -245,6 +248,10 @@ export class ConfigOptions {
|
||||
this.reportOptionalIterable = this._convertDiagnosticLevel(
|
||||
configObj.reportOptionalIterable, 'reportOptionalIterable', 'none');
|
||||
|
||||
// Read the "reportOptionalContextManager" entry.
|
||||
this.reportOptionalContextManager = this._convertDiagnosticLevel(
|
||||
configObj.reportOptionalContextManager, 'reportOptionalContextManager', 'none');
|
||||
|
||||
// Read the "reportUntypedFunctionDecorator" entry.
|
||||
this.reportUntypedFunctionDecorator = this._convertDiagnosticLevel(
|
||||
configObj.reportUntypedFunctionDecorator, 'reportUntypedFunctionDecorator', 'none');
|
||||
|
@ -7,6 +7,9 @@ class Foo:
|
||||
def do_stuff(self):
|
||||
pass
|
||||
|
||||
def __enter__(self):
|
||||
return 3
|
||||
|
||||
a = None
|
||||
if 1:
|
||||
a = Foo()
|
||||
@ -41,3 +44,12 @@ c[2]
|
||||
# this should generate an error.
|
||||
for val in c:
|
||||
pass
|
||||
|
||||
# If "reportOptionalContextManager" is enabled,
|
||||
# this should generate an error.
|
||||
cm = None
|
||||
if 1:
|
||||
cm = Foo()
|
||||
with cm as val:
|
||||
pass
|
||||
|
||||
|
@ -199,16 +199,18 @@ test('Optional1', () => {
|
||||
configOptions.reportOptionalMemberAccess = 'warning';
|
||||
configOptions.reportOptionalCall = 'warning';
|
||||
configOptions.reportOptionalIterable = 'warning';
|
||||
configOptions.reportOptionalContextManager = 'warning';
|
||||
analysisResults = TestUtils.typeAnalyzeSampleFiles(['optional1.py'], configOptions);
|
||||
validateResults(analysisResults, 0, 4);
|
||||
validateResults(analysisResults, 0, 5);
|
||||
|
||||
// Turn on errors.
|
||||
configOptions.reportOptionalSubscript = 'error';
|
||||
configOptions.reportOptionalMemberAccess = 'error';
|
||||
configOptions.reportOptionalCall = 'error';
|
||||
configOptions.reportOptionalIterable = 'error';
|
||||
configOptions.reportOptionalContextManager = 'error';
|
||||
analysisResults = TestUtils.typeAnalyzeSampleFiles(['optional1.py'], configOptions);
|
||||
validateResults(analysisResults, 4);
|
||||
validateResults(analysisResults, 5);
|
||||
});
|
||||
|
||||
test('Private1', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user