diff --git a/src/Analysis/Engine/Impl/Analyzer/ExpressionEvaluator.cs b/src/Analysis/Engine/Impl/Analyzer/ExpressionEvaluator.cs index d87aa3fcf..c45691a34 100644 --- a/src/Analysis/Engine/Impl/Analyzer/ExpressionEvaluator.cs +++ b/src/Analysis/Engine/Impl/Analyzer/ExpressionEvaluator.cs @@ -150,7 +150,7 @@ public IAnalysisSet LookupAnalysisSetByName(Node node, string name, bool addRef res = refs.Types; } else { // ... warn the user - warn = !(node is ConstantExpression); // Don't warn when None. + warn = true; } } } diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.cs index 2e0f5d5d0..c566002d2 100644 --- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.cs +++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.cs @@ -90,9 +90,9 @@ protected override PythonWalker PrepareWalker(IPythonInterpreter interpreter, Py #endif var walker = new AstAnalysisWalker( - interpreter, ast, this, filePath, null, _members, - includeLocations, - warnAboutUndefinedValues: true, + interpreter, ast, this, filePath, null, _members, + includeLocations, + warnAboutUndefinedValues: true, suppressBuiltinLookup: true ); walker.CreateBuiltinTypes = true; @@ -100,12 +100,11 @@ protected override PythonWalker PrepareWalker(IPythonInterpreter interpreter, Py } protected override void PostWalk(PythonWalker walker) { - IPythonType boolType = null; + AstPythonBuiltinType boolType = null; + AstPythonBuiltinType noneType = null; foreach (BuiltinTypeId typeId in Enum.GetValues(typeof(BuiltinTypeId))) { - IMember m; - AstPythonBuiltinType biType; - if (_members.TryGetValue("__{0}__".FormatInvariant(typeId), out m) && (biType = m as AstPythonBuiltinType) != null) { + if (_members.TryGetValue("__{0}__".FormatInvariant(typeId), out IMember m) && m is AstPythonBuiltinType biType) { if (typeId != BuiltinTypeId.Str && typeId != BuiltinTypeId.StrIterator) { biType.TrySetTypeId(typeId); @@ -117,7 +116,11 @@ protected override void PostWalk(PythonWalker walker) { _hiddenNames.Add("__{0}__".FormatInvariant(typeId)); if (typeId == BuiltinTypeId.Bool) { - boolType = m as IPythonType; + boolType = boolType ?? biType; + } + + if (typeId == BuiltinTypeId.NoneType) { + noneType = noneType ?? biType; } } } @@ -127,6 +130,10 @@ protected override void PostWalk(PythonWalker walker) { _members["True"] = _members["False"] = new AstPythonConstant(boolType); } + if (noneType != null) { + _members["None"] = new AstPythonConstant(noneType); + } + base.PostWalk(walker); } diff --git a/src/Analysis/Engine/Test/LanguageServerTests.cs b/src/Analysis/Engine/Test/LanguageServerTests.cs index 1985fe032..974499161 100644 --- a/src/Analysis/Engine/Test/LanguageServerTests.cs +++ b/src/Analysis/Engine/Test/LanguageServerTests.cs @@ -363,18 +363,15 @@ public async Task DiagnosticsSettingChange() { } } - [TestMethod, Priority(0)] - public async Task TypeHintNoneDiagnostic() { + [DataRow("def f(b: None) -> None:\n b: None")] + [DataRow("from typing import Generator\ndef fun() -> Generator[int, None, None]:\n yield from range(10)")] + [DataTestMethod, Priority(0)] + public async Task TypeHintNoneDiagnostic(string code) { if (this is LanguageServerTests_V2) { // No type hints in Python 2. return; } - var code = @" -def f(b: None) -> None: - b: None -"; - var diags = new Dictionary(); using (var s = await CreateServer((Uri)null, null, diags)) { var u = await s.OpenDefaultDocumentAndGetUriAsync(code);