Skip to content

Commit 043835a

Browse files
committed
Fix microsoft#719: Scraper produces incorrect output for the Anaconda 2X builtin
1 parent 63b6e30 commit 043835a

File tree

11 files changed

+91
-11
lines changed

11 files changed

+91
-11
lines changed

src/Analysis/Ast/Impl/Analyzer/Handlers/ImportHandler.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ private bool HandleImportSearchResult(in IImportSearchResult imports, in PythonV
8686
return TryGetModulePossibleImport(possibleModuleImport, parent, location, out variableModule);
8787
case ImplicitPackageImport packageImport:
8888
return TryGetPackageFromImport(packageImport, parent, out variableModule);
89+
case RelativeImportBeyondTopLevel importBeyondTopLevel:
90+
var message = Resources.ErrorRelativeImportBeyondTopLevel.FormatInvariant(importBeyondTopLevel.RelativeImportName);
91+
Eval.ReportDiagnostics(Eval.Module.Uri, new DiagnosticsEntry(message, location.Span, ErrorCodes.UnresolvedImport, Severity.Warning));
92+
variableModule = default;
93+
return false;
8994
case ImportNotFound importNotFound:
9095
var memberName = asNameExpression?.Name ?? importNotFound.FullName;
9196
MakeUnresolvedImport(memberName, importNotFound.FullName, location);

src/Analysis/Ast/Impl/Analyzer/PythonAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public sealed class PythonAnalyzer : IPythonAnalyzer, IDisposable {
4141
private readonly AsyncAutoResetEvent _analysisRunningEvent = new AsyncAutoResetEvent();
4242
private readonly ProgressReporter _progress;
4343
private readonly ILogger _log;
44-
private readonly int _maxTaskRunning = 8;
44+
private readonly int _maxTaskRunning = Environment.ProcessorCount * 3;
4545
private int _runningTasks;
4646
private int _version;
4747

src/Analysis/Ast/Impl/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Analysis/Ast/Impl/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@
312312
<data name="ErrorUnresolvedImport" xml:space="preserve">
313313
<value>unresolved import '{0}'</value>
314314
</data>
315+
<data name="ErrorRelativeImportBeyondTopLevel" xml:space="preserve">
316+
<value>Relative import '{0}' beyond top-level package</value>
317+
</data>
315318
<data name="ErrorUseBeforeDef" xml:space="preserve">
316319
<value>'{0}' used before definition</value>
317320
</data>

src/Analysis/Ast/Impl/scrape_module.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
import tokenize
2929
import warnings
3030

31-
try:
32-
import builtins
33-
except ImportError:
31+
if sys.version_info >= (3, 0):
32+
try:
33+
import builtins
34+
except ImportError:
35+
import __builtin__ as builtins
36+
else:
3437
import __builtin__ as builtins
3538

3639
try:

src/Analysis/Ast/Test/BasicTests.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
using Microsoft.Python.Analysis.Tests.FluentAssertions;
2020
using Microsoft.Python.Analysis.Types;
2121
using Microsoft.Python.Analysis.Values;
22+
using Microsoft.Python.Parsing;
23+
using Microsoft.Python.Parsing.Tests;
2224
using Microsoft.Python.Tests.Utilities.FluentAssertions;
2325
using Microsoft.VisualStudio.TestTools.UnitTesting;
2426
using TestUtilities;
@@ -83,12 +85,19 @@ import sys
8385
.And.HaveVariable("x").OfType(BuiltinTypeId.List);
8486
}
8587

86-
[TestMethod, Priority(0)]
87-
public async Task BuiltinsTest() {
88+
[DataRow(true, true)]
89+
[DataRow(false, true)]
90+
[DataRow(true, false)]
91+
[DataRow(false, false)]
92+
[DataTestMethod, Priority(0)]
93+
public async Task BuiltinsTest(bool isPython3X, bool isAnaconda) {
8894
const string code = @"
8995
x = 1
9096
";
91-
var analysis = await GetAnalysisAsync(code);
97+
var configuration = isPython3X
98+
? isAnaconda ? PythonVersions.LatestAnaconda3X : PythonVersions.LatestAvailable3X
99+
: isAnaconda ? PythonVersions.LatestAnaconda2X : PythonVersions.LatestAvailable2X;
100+
var analysis = await GetAnalysisAsync(code, configuration);
92101

93102
var v = analysis.Should().HaveVariable("x").Which;
94103
var t = v.Value.GetPythonType();

src/Analysis/Ast/Test/ImportTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ public async Task UnresolvedRelativeFromImportAs() {
212212
var d = analysis.Diagnostics.First();
213213
d.ErrorCode.Should().Be(ErrorCodes.UnresolvedImport);
214214
d.SourceSpan.Should().Be(1, 6, 1, 19);
215-
d.Message.Should().Be(Resources.ErrorUnresolvedImport.FormatInvariant("nonexistent"));
215+
d.Message.Should().Be(Resources.ErrorRelativeImportBeyondTopLevel.FormatInvariant("nonexistent"));
216216
}
217217
}
218218
}

src/Analysis/Core/Impl/DependencyResolution/PathResolverSnapshot.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ public IImportSearchResult GetImportsFromRelativePath(in string modulePath, in i
190190
return default;
191191
}
192192

193-
if (parentCount > lastEdge.PathLength) {
193+
if (parentCount >= lastEdge.PathLength) {
194194
// Can't get outside of the root
195-
return default;
195+
return new RelativeImportBeyondTopLevel(string.Join(".", relativePath));
196196
}
197197

198198
var fullNameList = relativePath.TakeWhile(n => !string.IsNullOrEmpty(n)).ToList();
@@ -208,7 +208,7 @@ public IImportSearchResult GetImportsFromRelativePath(in string modulePath, in i
208208

209209
return new ImportNotFound(new StringBuilder(lastEdge.Start.Name)
210210
.Append(".")
211-
.Append(fullNameList)
211+
.Append(".", fullNameList)
212212
.ToString());
213213
}
214214

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright(c) Microsoft Corporation
2+
// All rights reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the License); you may not use
5+
// this file except in compliance with the License. You may obtain a copy of the
6+
// License at http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
9+
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
10+
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
11+
// MERCHANTABILITY OR NON-INFRINGEMENT.
12+
//
13+
// See the Apache Version 2.0 License for specific language governing
14+
// permissions and limitations under the License.
15+
16+
namespace Microsoft.Python.Analysis.Core.DependencyResolution {
17+
public class RelativeImportBeyondTopLevel : IImportSearchResult {
18+
public string RelativeImportName { get; }
19+
public RelativeImportBeyondTopLevel(string relativeImportName) {
20+
RelativeImportName = relativeImportName;
21+
}
22+
}
23+
}

src/LanguageServer/Test/CompletionTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,26 @@ public async Task FromDotInRoot() {
903903
result.Should().HaveNoCompletion();
904904
}
905905

906+
[TestMethod, Priority(0)]
907+
public async Task FromDotInRootWithInitPy() {
908+
var initPyPath = TestData.GetTestSpecificUri("__init__.py");
909+
var module1Path = TestData.GetTestSpecificUri("module1.py");
910+
911+
var root = TestData.GetTestSpecificRootUri().AbsolutePath;
912+
await CreateServicesAsync(root, PythonVersions.LatestAvailable3X);
913+
var rdt = Services.GetService<IRunningDocumentTable>();
914+
915+
rdt.OpenDocument(initPyPath, string.Empty);
916+
var module1 = rdt.OpenDocument(module1Path, "from .");
917+
module1.Interpreter.ModuleResolution.GetOrLoadModule("__init__");
918+
919+
var analysis = await module1.GetAnalysisAsync(-1);
920+
921+
var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
922+
var result = cs.GetCompletions(analysis, new SourceLocation(1, 7));
923+
result.Should().HaveNoCompletion();
924+
}
925+
906926
[TestMethod, Priority(0)]
907927
public async Task FromDotInExplicitPackage() {
908928
var initPyPath = TestData.GetTestSpecificUri("package", "__init__.py");

src/Parsing/Test/PythonVersions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ public static class PythonVersions {
8181
Python27,
8282
Python27_x64).FirstOrDefault() ?? NotInstalled("v2");
8383

84+
public static InterpreterConfiguration LatestAnaconda3X => GetVersions(
85+
Anaconda36,
86+
Anaconda36_x64).FirstOrDefault() ?? NotInstalled("Anaconda v3");
87+
88+
public static InterpreterConfiguration LatestAnaconda2X => GetVersions(
89+
Anaconda27,
90+
Anaconda27_x64).FirstOrDefault() ?? NotInstalled("Anaconda v2");
91+
8492
public static InterpreterConfiguration EarliestAvailable => EarliestAvailable2X ?? EarliestAvailable3X;
8593

8694
public static InterpreterConfiguration EarliestAvailable3X => GetVersions(

0 commit comments

Comments
 (0)