diff --git a/src/Analysis/Ast/Impl/Analyzer/Handlers/FromImportHandler.cs b/src/Analysis/Ast/Impl/Analyzer/Handlers/FromImportHandler.cs
index 3374d04b2..7975f97d2 100644
--- a/src/Analysis/Ast/Impl/Analyzer/Handlers/FromImportHandler.cs
+++ b/src/Analysis/Ast/Impl/Analyzer/Handlers/FromImportHandler.cs
@@ -59,7 +59,7 @@ private void AssignVariables(FromImportStatement node, IImportSearchResult impor
// TODO: warn this is not a good style per
// TODO: https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module
// TODO: warn this is invalid if not in the global scope.
- HandleModuleImportStar(variableModule, imports is ImplicitPackageImport, node.StartIndex);
+ HandleModuleImportStar(variableModule, imports, node.StartIndex, names[0]);
return;
}
@@ -69,43 +69,51 @@ private void AssignVariables(FromImportStatement node, IImportSearchResult impor
var nameExpression = asNames[i] ?? names[i];
var variableName = nameExpression?.Name ?? memberName;
if (!string.IsNullOrEmpty(variableName)) {
- var variable = variableModule.Analysis?.GlobalScope?.Variables[memberName];
- var exported = variable ?? variableModule.GetMember(memberName);
- var value = exported ?? GetValueFromImports(variableModule, imports as IImportChildrenSource, memberName);
- // Do not allow imported variables to override local declarations
- Eval.DeclareVariable(variableName, value, VariableSource.Import, nameExpression, CanOverwriteVariable(variableName, node.StartIndex));
+ DeclareVariable(variableModule, memberName, imports, variableName, node.StartIndex, nameExpression);
}
}
}
}
- private void HandleModuleImportStar(PythonVariableModule variableModule, bool isImplicitPackage, int importPosition) {
+ private void HandleModuleImportStar(PythonVariableModule variableModule, IImportSearchResult imports, int importPosition, NameExpression nameExpression) {
if (variableModule.Module == Module) {
// from self import * won't define any new members
return;
}
-
// If __all__ is present, take it, otherwise declare all members from the module that do not begin with an underscore.
- var memberNames = isImplicitPackage
+ var memberNames = imports is ImplicitPackageImport
? variableModule.GetMemberNames()
: variableModule.Analysis.StarImportMemberNames ?? variableModule.GetMemberNames().Where(s => !s.StartsWithOrdinal("_"));
foreach (var memberName in memberNames) {
- var member = variableModule.GetMember(memberName);
- if (member == null) {
- Log?.Log(TraceEventType.Verbose, $"Undefined import: {variableModule.Name}, {memberName}");
- } else if (member.MemberType == PythonMemberType.Unknown) {
- Log?.Log(TraceEventType.Verbose, $"Unknown import: {variableModule.Name}, {memberName}");
- }
-
- member = member ?? Eval.UnknownType;
- if (member is IPythonModule m) {
- ModuleResolution.GetOrLoadModule(m.Name);
- }
+ DeclareVariable(variableModule, memberName, imports, memberName, importPosition, nameExpression);
+ }
+ }
- var variable = variableModule.Analysis?.GlobalScope?.Variables[memberName];
- // Do not allow imported variables to override local declarations
- Eval.DeclareVariable(memberName, variable ?? member, VariableSource.Import, Eval.DefaultLocation, CanOverwriteVariable(memberName, importPosition));
+ ///
+ /// Determines value of the variable and declares it. Value depends if source module has submodule
+ /// that is named the same as the variable and/or it has internal variables named same as the submodule.
+ ///
+ /// 'from a.b import c' when 'c' is both submodule of 'b' and a variable declared inside 'b'.
+ /// Source module of the variable such as 'a.b' in 'from a.b import c as d'.
+ /// Module member name such as 'c' in 'from a.b import c as d'.
+ /// Import search result.
+ /// Name of the variable to declare, such as 'd' in 'from a.b import c as d'.
+ /// Position of the import statement.
+ /// Name expression of the variable.
+ private void DeclareVariable(PythonVariableModule variableModule, string memberName, IImportSearchResult imports, string variableName, int importPosition, Node nameExpression) {
+ // First try imports since child modules should win, i.e. in 'from a.b import c'
+ // 'c' should be a submodule if 'b' has one, even if 'b' also declares 'c = 1'.
+ var value = GetValueFromImports(variableModule, imports as IImportChildrenSource, memberName);
+ // Now try exported
+ value = value ?? variableModule.GetMember(memberName);
+ // If nothing is exported, variables are still accessible.
+ value = value ?? variableModule.Analysis?.GlobalScope?.Variables[memberName]?.Value ?? Eval.UnknownType;
+ // Do not allow imported variables to override local declarations
+ Eval.DeclareVariable(variableName, value, VariableSource.Import, nameExpression, CanOverwriteVariable(variableName, importPosition));
+ // Make sure module is loaded and analyzed.
+ if (value is IPythonModule m) {
+ ModuleResolution.GetOrLoadModule(m.Name);
}
}
@@ -131,7 +139,7 @@ private bool CanOverwriteVariable(string name, int importPosition) {
private IMember GetValueFromImports(PythonVariableModule parentModule, IImportChildrenSource childrenSource, string memberName) {
if (childrenSource == null || !childrenSource.TryGetChildImport(memberName, out var childImport)) {
- return Interpreter.UnknownType;
+ return null;
}
switch (childImport) {
@@ -141,7 +149,7 @@ private IMember GetValueFromImports(PythonVariableModule parentModule, IImportCh
case ImplicitPackageImport packageImport:
return GetOrCreateVariableModule(packageImport.FullName, parentModule, memberName);
default:
- return Interpreter.UnknownType;
+ return null;
}
}
diff --git a/src/Analysis/Ast/Impl/Analyzer/Handlers/ImportHandler.cs b/src/Analysis/Ast/Impl/Analyzer/Handlers/ImportHandler.cs
index 7999d0e2a..62170c8be 100644
--- a/src/Analysis/Ast/Impl/Analyzer/Handlers/ImportHandler.cs
+++ b/src/Analysis/Ast/Impl/Analyzer/Handlers/ImportHandler.cs
@@ -56,27 +56,47 @@ private void HandleImport(ModuleName moduleImportExpression, NameExpression asNa
// import_module('fob.oar.baz')
var importNames = ImmutableArray.Empty;
var lastModule = default(PythonVariableModule);
- var firstModule = default(PythonVariableModule);
- foreach (var nameExpression in moduleImportExpression.Names) {
+ var resolvedModules = new (string name, PythonVariableModule module)[moduleImportExpression.Names.Count];
+ for (var i = 0; i < moduleImportExpression.Names.Count; i++) {
+ var nameExpression = moduleImportExpression.Names[i];
importNames = importNames.Add(nameExpression.Name);
var imports = ModuleResolution.CurrentPathResolver.GetImportsFromAbsoluteName(Module.FilePath, importNames, forceAbsolute);
if (!HandleImportSearchResult(imports, lastModule, asNameExpression, moduleImportExpression, out lastModule)) {
lastModule = default;
break;
}
-
- if (firstModule == null) {
- firstModule = lastModule;
- }
+ resolvedModules[i] = (nameExpression.Name, lastModule);
}
// "import fob.oar.baz as baz" is handled as baz = import_module('fob.oar.baz')
- // "import fob.oar.baz" is handled as fob = import_module('fob')
if (!string.IsNullOrEmpty(asNameExpression?.Name) && lastModule != null) {
Eval.DeclareVariable(asNameExpression.Name, lastModule, VariableSource.Import, asNameExpression);
- } else if (firstModule != null && !string.IsNullOrEmpty(importNames[0])) {
- var firstName = moduleImportExpression.Names[0];
- Eval.DeclareVariable(importNames[0], firstModule, VariableSource.Import, firstName);
+ return;
+ }
+
+ var firstModule = resolvedModules.Length > 0 ? resolvedModules[0].module : null;
+ var secondModule = resolvedModules.Length > 1 ? resolvedModules[1].module : null;
+
+ // "import fob.oar.baz" when 'fob' is THIS module handled by declaring 'oar' as member.
+ // Consider pandas that has 'import pandas.testing' in __init__.py and 'testing'
+ // is available as member. See also https://github.com/microsoft/python-language-server/issues/1395
+ if (firstModule?.Module == Eval.Module && importNames.Count > 1 && !string.IsNullOrEmpty(importNames[1]) && secondModule != null) {
+ Eval.DeclareVariable(importNames[0], firstModule, VariableSource.Import, moduleImportExpression.Names[0]);
+ Eval.DeclareVariable(importNames[1], secondModule, VariableSource.Import, moduleImportExpression.Names[1]);
+ } else {
+ // "import fob.oar.baz" is handled as fob = import_module('fob')
+ if (firstModule != null && !string.IsNullOrEmpty(importNames[0])) {
+ Eval.DeclareVariable(importNames[0], firstModule, VariableSource.Import, moduleImportExpression.Names[0]);
+ }
+ }
+
+ // import a.b.c.d => declares a, b in the current module, c in b, d in c.
+ for (var i = 1; i < resolvedModules.Length - 1; i++) {
+ var (childName, childModule) = resolvedModules[i + 1];
+ if (!string.IsNullOrEmpty(childName) && childModule != null) {
+ var parent = resolvedModules[i].module;
+ parent?.AddChildModule(childName, childModule);
+ }
}
}
@@ -92,7 +112,7 @@ private bool HandleImportSearchResult(in IImportSearchResult imports, in PythonV
return TryGetPackageFromImport(packageImport, parent, out variableModule);
case RelativeImportBeyondTopLevel importBeyondTopLevel:
var message = Resources.ErrorRelativeImportBeyondTopLevel.FormatInvariant(importBeyondTopLevel.RelativeImportName);
- Eval.ReportDiagnostics(Eval.Module.Uri,
+ Eval.ReportDiagnostics(Eval.Module.Uri,
new DiagnosticsEntry(message, location.GetLocation(Eval).Span, ErrorCodes.UnresolvedImport, Severity.Warning, DiagnosticSource.Analysis));
variableModule = default;
return false;
@@ -157,7 +177,7 @@ private bool TryGetModulePossibleImport(PossibleModuleImport possibleModuleImpor
return false;
}
}
-
+
return true;
}
@@ -170,8 +190,8 @@ private void MakeUnresolvedImport(string variableName, string moduleName, Node l
if (!string.IsNullOrEmpty(variableName)) {
Eval.DeclareVariable(variableName, new SentinelModule(moduleName, Eval.Services), VariableSource.Import, location);
}
- Eval.ReportDiagnostics(Eval.Module.Uri,
- new DiagnosticsEntry(Resources.ErrorUnresolvedImport.FormatInvariant(moduleName),
+ Eval.ReportDiagnostics(Eval.Module.Uri,
+ new DiagnosticsEntry(Resources.ErrorUnresolvedImport.FormatInvariant(moduleName),
Eval.GetLocationInfo(location).Span, ErrorCodes.UnresolvedImport, Severity.Warning, DiagnosticSource.Analysis));
}
diff --git a/src/Analysis/Ast/Impl/Extensions/PythonModuleExtensions.cs b/src/Analysis/Ast/Impl/Extensions/PythonModuleExtensions.cs
index caa2b5b34..c05e062c3 100644
--- a/src/Analysis/Ast/Impl/Extensions/PythonModuleExtensions.cs
+++ b/src/Analysis/Ast/Impl/Extensions/PythonModuleExtensions.cs
@@ -13,8 +13,12 @@
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Python.Analysis.Core.DependencyResolution;
using Microsoft.Python.Analysis.Modules;
using Microsoft.Python.Analysis.Types;
+using Microsoft.Python.Core;
using Microsoft.Python.Core.Text;
using Microsoft.Python.Parsing.Ast;
@@ -39,12 +43,12 @@ internal static void AddAstNode(this IPythonModule module, object o, Node n)
///
/// The line number
internal static string GetLine(this IPythonModule module, int lineNum) {
- string content = module.Analysis?.Document?.Content;
+ var content = module.Analysis?.Document?.Content;
if (string.IsNullOrEmpty(content)) {
return string.Empty;
}
- SourceLocation source = new SourceLocation(lineNum, 1);
+ var source = new SourceLocation(lineNum, 1);
var start = module.GetAst().LocationToIndex(source);
var end = start;
@@ -58,9 +62,9 @@ internal static string GetLine(this IPythonModule module, int lineNum) {
///
/// The line number
internal static string GetComment(this IPythonModule module, int lineNum) {
- string line = module.GetLine(lineNum);
+ var line = module.GetLine(lineNum);
- int commentPos = line.IndexOf('#');
+ var commentPos = line.IndexOf('#');
if (commentPos < 0) {
return string.Empty;
}
@@ -68,7 +72,8 @@ internal static string GetComment(this IPythonModule module, int lineNum) {
return line.Substring(commentPos + 1).Trim('\t', ' ');
}
- internal static bool IsNonUserFile(this IPythonModule module) => module.ModuleType.IsNonUserFile();
- internal static bool IsCompiled(this IPythonModule module) => module.ModuleType.IsCompiled();
+ public static bool IsNonUserFile(this IPythonModule module) => module.ModuleType.IsNonUserFile();
+ public static bool IsCompiled(this IPythonModule module) => module.ModuleType.IsCompiled();
+ public static bool IsTypingModule(this IPythonModule module) => module?.ModuleType == ModuleType.Specialized && module.Name == "typing";
}
}
diff --git a/src/Analysis/Ast/Impl/Modules/PythonModule.cs b/src/Analysis/Ast/Impl/Modules/PythonModule.cs
index af216a813..92de189dd 100644
--- a/src/Analysis/Ast/Impl/Modules/PythonModule.cs
+++ b/src/Analysis/Ast/Impl/Modules/PythonModule.cs
@@ -158,6 +158,7 @@ public virtual string Documentation {
#region IMemberContainer
public virtual IMember GetMember(string name) => GlobalScope.Variables[name]?.Value;
+
public virtual IEnumerable GetMemberNames() {
// drop imported modules and typing.
return GlobalScope.Variables
@@ -166,26 +167,26 @@ public virtual IEnumerable GetMemberNames() {
if (v.Value is IPythonInstance) {
return true;
}
+
var valueType = v.Value?.GetPythonType();
- if (valueType is PythonModule) {
- return false; // Do not re-export modules.
- }
- if (valueType is IPythonFunctionType f && f.IsLambda()) {
- return false;
+ switch (valueType) {
+ case PythonModule _:
+ case IPythonFunctionType f when f.IsLambda():
+ return false; // Do not re-export modules.
}
+
if (this is TypingModule) {
return true; // Let typing module behave normally.
}
+
// Do not re-export types from typing. However, do export variables
// assigned with types from typing. Example:
// from typing import Any # do NOT export Any
// x = Union[int, str] # DO export x
- if (valueType?.DeclaringModule is TypingModule && v.Name == valueType.Name) {
- return false;
- }
- return true;
+ return !(valueType?.DeclaringModule is TypingModule) || v.Name != valueType.Name;
})
- .Select(v => v.Name);
+ .Select(v => v.Name)
+ .ToArray();
}
#endregion
diff --git a/src/Analysis/Ast/Impl/Modules/PythonVariableModule.cs b/src/Analysis/Ast/Impl/Modules/PythonVariableModule.cs
index 70e4c9fab..6641a3c8a 100644
--- a/src/Analysis/Ast/Impl/Modules/PythonVariableModule.cs
+++ b/src/Analysis/Ast/Impl/Modules/PythonVariableModule.cs
@@ -67,8 +67,8 @@ public PythonVariableModule(IPythonModule module): base(module) {
public void AddChildModule(string memberName, PythonVariableModule module) => _children[memberName] = module;
- public IMember GetMember(string name) => Module?.GetMember(name) ?? (_children.TryGetValue(name, out var module) ? module : default);
- public IEnumerable GetMemberNames() => Module != null ? Module.GetMemberNames().Concat(_children.Keys) : _children.Keys;
+ public IMember GetMember(string name) => _children.TryGetValue(name, out var module) ? module : Module?.GetMember(name);
+ public IEnumerable GetMemberNames() => Module != null ? Module.GetMemberNames().Concat(_children.Keys).Distinct() : _children.Keys;
public IMember Call(IPythonInstance instance, string memberName, IArgumentSet args) => GetMember(memberName);
public IMember Index(IPythonInstance instance, IArgumentSet args) => Interpreter.UnknownType;
diff --git a/src/Analysis/Ast/Test/FluentAssertions/MemberAssertions.cs b/src/Analysis/Ast/Test/FluentAssertions/MemberAssertions.cs
index 871e0a37a..1f6b10c08 100644
--- a/src/Analysis/Ast/Test/FluentAssertions/MemberAssertions.cs
+++ b/src/Analysis/Ast/Test/FluentAssertions/MemberAssertions.cs
@@ -83,6 +83,20 @@ public AndWhichConstraint HaveBase(string name, s
public AndWhichConstraint HaveMethod(string name, string because = "", params object[] reasonArgs)
=> HaveMember(name, because, reasonArgs).OfMemberType(PythonMemberType.Method);
+ public void HaveMemberName(string name, string because = "", params object[] reasonArgs) {
+ NotBeNull();
+
+ var t = Subject.GetPythonType();
+ var mc = (IMemberContainer)t;
+ Execute.Assertion.ForCondition(mc != null)
+ .BecauseOf(because, reasonArgs)
+ .FailWith($"Expected {GetName(t)} to be a member container{{reason}}.");
+
+ Execute.Assertion.ForCondition(mc.GetMemberNames().Contains(name))
+ .BecauseOf(because, reasonArgs)
+ .FailWith($"Expected {GetName(t)} to have a member named '{name}'{{reason}}.");
+ }
+
public AndWhichConstraint HaveMember(string name,
string because = "", params object[] reasonArgs)
where TMember : class, IMember {
@@ -125,7 +139,7 @@ public void HaveSameMembersAs(IMember other) {
Debug.Assert(missingNames.Length == 0);
missingNames.Should().BeEmpty("Subject has missing names: ", missingNames);
-
+
Debug.Assert(extraNames.Length == 0);
extraNames.Should().BeEmpty("Subject has extra names: ", extraNames);
@@ -147,7 +161,7 @@ public void HaveSameMembersAs(IMember other) {
var otherClass = otherMemberType as IPythonClassType;
otherClass.Should().NotBeNull();
- if(subjectClass is IGenericType gt) {
+ if (subjectClass is IGenericType gt) {
otherClass.Should().BeAssignableTo();
otherClass.IsGeneric.Should().Be(gt.IsGeneric, $"Class name: {subjectClass.Name}");
}
diff --git a/src/Analysis/Ast/Test/FluentAssertions/VariableAssertions.cs b/src/Analysis/Ast/Test/FluentAssertions/VariableAssertions.cs
index 6f0aac0c1..fff01147f 100644
--- a/src/Analysis/Ast/Test/FluentAssertions/VariableAssertions.cs
+++ b/src/Analysis/Ast/Test/FluentAssertions/VariableAssertions.cs
@@ -65,8 +65,7 @@ public AndWhichConstraint HaveMember(string name, s
public AndWhichConstraint NotHaveMember(string name, string because = "", params object[] reasonArgs) {
NotBeNull(because, reasonArgs);
- var m = Value.GetPythonType().GetMember(name);
- m.GetPythonType().IsUnknown().Should().BeTrue();
+ Value.GetPythonType().GetMemberNames().Should().NotContain(name);
return new AndWhichConstraint(this, Subject);
}
@@ -90,6 +89,11 @@ public AndWhichConstraint HaveMember(string name, stri
return new AndWhichConstraint(this, m);
}
+ public void HaveMemberName(string name, string because = "", params object[] reasonArgs) {
+ NotBeNull(because, reasonArgs);
+ Value.GetPythonType().GetMemberNames().Should().Contain(name);
+ }
+
public AndWhichConstraint HaveOverloadWithParametersAt(int index, string because = "", params object[] reasonArgs) {
var constraint = HaveOverloadAt(index);
var overload = constraint.Which;
diff --git a/src/Analysis/Ast/Test/ImportTests.cs b/src/Analysis/Ast/Test/ImportTests.cs
index 7878adf65..2b7ce0c7c 100644
--- a/src/Analysis/Ast/Test/ImportTests.cs
+++ b/src/Analysis/Ast/Test/ImportTests.cs
@@ -24,6 +24,7 @@
using Microsoft.Python.Analysis.Modules;
using Microsoft.Python.Analysis.Tests.FluentAssertions;
using Microsoft.Python.Analysis.Types;
+using Microsoft.Python.Analysis.Values;
using Microsoft.Python.Core;
using Microsoft.Python.Parsing.Tests;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -239,6 +240,58 @@ def exit():
analysis.Should().HaveVariable("x").OfType(BuiltinTypeId.Int);
}
+ [TestMethod, Priority(0)]
+ public async Task ModuleInternalImportSys() {
+ var appUri = TestData.GetTestSpecificUri("app.py");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("package", "__init__.py"), "from . import m1\nimport sys");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("package", "m1", "__init__.py"), string.Empty);
+
+ await CreateServicesAsync(PythonVersions.LatestAvailable3X);
+ var rdt = Services.GetService();
+ var doc = rdt.OpenDocument(appUri, "import package");
+
+ await Services.GetService().WaitForCompleteAnalysisAsync();
+ var analysis = await doc.GetAnalysisAsync(Timeout.Infinite);
+ analysis.Should().HaveVariable("package").Which.Should().HaveMembers("m1", "sys");
+ }
+
+ [TestMethod, Priority(0)]
+ public async Task ModuleImportingSubmodule() {
+ var appUri = TestData.GetTestSpecificUri("app.py");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("package", "__init__.py"), "import package.m1");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("package", "m1", "__init__.py"), string.Empty);
+
+ await CreateServicesAsync(PythonVersions.LatestAvailable3X);
+ var rdt = Services.GetService();
+ var doc = rdt.OpenDocument(appUri, "import package");
+
+ await Services.GetService().WaitForCompleteAnalysisAsync();
+ var analysis = await doc.GetAnalysisAsync(Timeout.Infinite);
+ analysis.Should().HaveVariable("package").Which.Should().HaveMember("m1");
+ }
+
+ [TestMethod, Priority(0)]
+ public async Task ModuleImportingSubmodules() {
+ var appUri = TestData.GetTestSpecificUri("app.py");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "__init__.py"), @"
+from top import sub1
+import top.sub2
+import top.sub3.sub4
+");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub2.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub3", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub3", "sub4.py"), string.Empty);
+
+ await CreateServicesAsync(PythonVersions.LatestAvailable3X);
+ var rdt = Services.GetService();
+ var doc = rdt.OpenDocument(appUri, "import top");
+
+ await Services.GetService().WaitForCompleteAnalysisAsync();
+ var analysis = await doc.GetAnalysisAsync(Timeout.Infinite);
+ analysis.Should().HaveVariable("top").Which.Should().HaveMembers("sub1", "sub2", "sub3", "top");
+ }
+
[TestMethod, Priority(0)]
public async Task ImportPackageNoInitPy() {
@@ -255,5 +308,69 @@ public async Task ImportPackageNoInitPy() {
.Which.Should().HaveType().Which;
sub1.Value.MemberType.Should().NotBe(ModuleType.Unresolved);
}
+
+ [TestMethod, Priority(0)]
+ public async Task DeepSubmoduleImport() {
+ var appUri = TestData.GetTestSpecificUri("app.py");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "sub2", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "sub2", "sub3", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "sub2", "sub3", "sub4", "__init__.py"), string.Empty);
+
+ await CreateServicesAsync(PythonVersions.LatestAvailable3X);
+ var rdt = Services.GetService();
+ var appDoc = rdt.OpenDocument(appUri, "import top.sub1.sub2.sub3.sub4");
+
+ await Services.GetService().WaitForCompleteAnalysisAsync();
+ var analysis = await appDoc.GetAnalysisAsync(Timeout.Infinite);
+
+ var topModule = analysis.Should().HaveVariable("top")
+ .Which.Should().HaveType().Which;
+
+ topModule.Should().HaveMemberName("sub1");
+ var sub1Module = topModule.Should().HaveMember("sub1").Which;
+
+ sub1Module.Should().HaveMemberName("sub2");
+ var sub2Module = sub1Module.Should().HaveMember("sub2").Which;
+
+ sub2Module.Should().HaveMemberName("sub3");
+ var sub3Module = sub2Module.Should().HaveMember("sub3").Which;
+
+ sub3Module.Should().HaveMemberName("sub4");
+ sub3Module.Should().HaveMember("sub4");
+ }
+
+ [TestMethod, Priority(0)]
+ public async Task SubmoduleOverridesVariable() {
+ var appUri = TestData.GetTestSpecificUri("app.py");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "__init__.py"), "sub2 = 1");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "sub2", "__init__.py"), string.Empty);
+
+ await CreateServicesAsync(PythonVersions.LatestAvailable3X);
+ var rdt = Services.GetService();
+ var appDoc = rdt.OpenDocument(appUri, "from top.sub1 import sub2");
+
+ await Services.GetService().WaitForCompleteAnalysisAsync();
+ var analysis = await appDoc.GetAnalysisAsync(Timeout.Infinite);
+ analysis.Should().HaveVariable("sub2").Which.Should().HaveType(BuiltinTypeId.Module);
+ }
+
+ [TestMethod, Priority(0)]
+ public async Task SubmoduleOverridesVariableStarImport() {
+ var appUri = TestData.GetTestSpecificUri("app.py");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "__init__.py"), "sub2 = 1");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("top", "sub1", "sub2", "__init__.py"), string.Empty);
+
+ await CreateServicesAsync(PythonVersions.LatestAvailable3X);
+ var rdt = Services.GetService();
+ var appDoc = rdt.OpenDocument(appUri, "from top.sub1 import *");
+
+ await Services.GetService().WaitForCompleteAnalysisAsync();
+ var analysis = await appDoc.GetAnalysisAsync(Timeout.Infinite);
+ analysis.Should().HaveVariable("sub2").Which.Should().HaveType(BuiltinTypeId.Module);
+ }
}
}
diff --git a/src/Analysis/Ast/Test/ScrapeTests.cs b/src/Analysis/Ast/Test/ScrapeTests.cs
index b3b854470..d3278475d 100644
--- a/src/Analysis/Ast/Test/ScrapeTests.cs
+++ b/src/Analysis/Ast/Test/ScrapeTests.cs
@@ -274,6 +274,7 @@ private async Task FullStdLibTest(InterpreterConfiguration configuration, params
var pathResolver = interpreter.ModuleResolution.CurrentPathResolver;
var modules = pathResolver.GetAllImportableModuleNames()
.Select(n => pathResolver.GetModuleImportFromModuleName(n))
+ .ExcludeDefault()
.Where(i => i.RootPath.PathEquals(configuration.SitePackagesPath) || i.RootPath.PathEquals(configuration.LibraryPath))
.ToList();
diff --git a/src/Analysis/Core/Impl/DependencyResolution/AstUtilities.cs b/src/Analysis/Core/Impl/DependencyResolution/AstUtilities.cs
index 57c93cc1d..8c7ee1457 100644
--- a/src/Analysis/Core/Impl/DependencyResolution/AstUtilities.cs
+++ b/src/Analysis/Core/Impl/DependencyResolution/AstUtilities.cs
@@ -13,9 +13,8 @@
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
-using System.Collections.Generic;
-using System.Linq;
using Microsoft.Python.Parsing.Ast;
+using System.Collections.Generic;
namespace Microsoft.Python.Analysis.Core.DependencyResolution {
public static class AstUtilities {
diff --git a/src/Analysis/Core/Impl/DependencyResolution/PathResolverSnapshot.cs b/src/Analysis/Core/Impl/DependencyResolution/PathResolverSnapshot.cs
index 1dd003ddb..68aa0f8c7 100644
--- a/src/Analysis/Core/Impl/DependencyResolution/PathResolverSnapshot.cs
+++ b/src/Analysis/Core/Impl/DependencyResolution/PathResolverSnapshot.cs
@@ -88,11 +88,14 @@ public ImmutableArray GetAllImportableModuleNames(bool includeImplicitPa
while (items.Count > 0) {
var item = items.Dequeue();
- if (!string.IsNullOrEmpty(item.FullModuleName) && (item.IsModule || includeImplicitPackages)) {
- names = names.Add(item.FullModuleName);
- }
- foreach (var child in item.Children) {
- items.Enqueue(child);
+ if (item != null) {
+ if (!string.IsNullOrEmpty(item.FullModuleName) && (item.IsModule || includeImplicitPackages)) {
+ names = names.Add(item.FullModuleName);
+ }
+
+ foreach (var child in item.Children.ExcludeDefault()) {
+ items.Enqueue(child);
+ }
}
}
diff --git a/src/LanguageServer/Impl/Completion/CompletionContext.cs b/src/LanguageServer/Impl/Completion/CompletionContext.cs
index b40f8a44b..f71f5b944 100644
--- a/src/LanguageServer/Impl/Completion/CompletionContext.cs
+++ b/src/LanguageServer/Impl/Completion/CompletionContext.cs
@@ -15,6 +15,7 @@
using System.Linq;
using Microsoft.Python.Analysis;
+using Microsoft.Python.Core;
using Microsoft.Python.Core.Text;
using Microsoft.Python.Parsing.Ast;
@@ -28,12 +29,14 @@ internal sealed class CompletionContext {
public int Position { get; }
public TokenSource TokenSource => _ts ?? (_ts = new TokenSource(Analysis.Document, Position));
public CompletionItemSource ItemSource { get; }
+ public IServiceContainer Services { get; }
- public CompletionContext(IDocumentAnalysis analysis, SourceLocation location, CompletionItemSource itemSource) {
+ public CompletionContext(IDocumentAnalysis analysis, SourceLocation location, CompletionItemSource itemSource, IServiceContainer services) {
Location = location;
Analysis = analysis;
Position = Ast.LocationToIndex(location);
ItemSource = itemSource;
+ Services = services;
}
public SourceLocation IndexToLocation(int index) => Ast.IndexToLocation(index);
diff --git a/src/LanguageServer/Impl/Completion/CompletionSource.cs b/src/LanguageServer/Impl/Completion/CompletionSource.cs
index 7f0a3f714..d8666c5a5 100644
--- a/src/LanguageServer/Impl/Completion/CompletionSource.cs
+++ b/src/LanguageServer/Impl/Completion/CompletionSource.cs
@@ -17,6 +17,7 @@
using Microsoft.Python.Analysis;
using Microsoft.Python.Analysis.Analyzer.Expressions;
using Microsoft.Python.Analysis.Modules;
+using Microsoft.Python.Core;
using Microsoft.Python.Core.Text;
using Microsoft.Python.Parsing;
using Microsoft.Python.Parsing.Ast;
@@ -24,9 +25,11 @@
namespace Microsoft.Python.LanguageServer.Completion {
internal sealed class CompletionSource {
private readonly CompletionItemSource _itemSource;
+ private readonly IServiceContainer _services;
- public CompletionSource(IDocumentationSource docSource, ServerSettings.PythonCompletionOptions completionSettings) {
+ public CompletionSource(IDocumentationSource docSource, ServerSettings.PythonCompletionOptions completionSettings, IServiceContainer services) {
_itemSource = new CompletionItemSource(docSource, completionSettings);
+ _services = services;
}
public ServerSettings.PythonCompletionOptions Options {
@@ -39,7 +42,7 @@ public CompletionResult GetCompletions(IDocumentAnalysis analysis, SourceLocatio
return CompletionResult.Empty;
}
- var context = new CompletionContext(analysis, location, _itemSource);
+ var context = new CompletionContext(analysis, location, _itemSource, _services);
ExpressionLocator.FindExpression(analysis.Ast, location,
FindExpressionOptions.Complete, out var expression, out var statement, out var scope);
diff --git a/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs b/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs
index 5e9ff8d33..9661cd263 100644
--- a/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs
+++ b/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs
@@ -13,13 +13,15 @@
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using Microsoft.Python.Analysis;
using Microsoft.Python.Analysis.Types;
using Microsoft.Python.Analysis.Values;
+using Microsoft.Python.Core.IO;
using Microsoft.Python.LanguageServer.Protocol;
using Microsoft.Python.Parsing.Ast;
-using System.Collections.Generic;
-using System.Linq;
namespace Microsoft.Python.LanguageServer.Completion {
internal static class ExpressionCompletion {
@@ -41,19 +43,12 @@ private static IEnumerable GetItemsFromExpression(Expression e,
if (!value.IsUnknown()) {
var type = value.GetPythonType();
- if(type is IPythonClassType cls) {
+ if (type is IPythonClassType cls) {
return GetClassItems(cls, e, context);
}
- var items = new List();
- foreach (var t in type.GetMemberNames().ToArray()) {
- var m = type.GetMember(t);
- if (m is IVariable v && v.Source != VariableSource.Declaration) {
- continue;
- }
- items.Add(context.ItemSource.CreateCompletionItem(t, m, type));
- }
- return items;
+ return type.GetMemberNames()
+ .Select(name => context.ItemSource.CreateCompletionItem(name, type.GetMember(name), type));
}
return Enumerable.Empty();
}
diff --git a/src/LanguageServer/Impl/Completion/ImportCompletion.cs b/src/LanguageServer/Impl/Completion/ImportCompletion.cs
index 2470bed43..a88fe129c 100644
--- a/src/LanguageServer/Impl/Completion/ImportCompletion.cs
+++ b/src/LanguageServer/Impl/Completion/ImportCompletion.cs
@@ -15,7 +15,6 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using Microsoft.Python.Analysis.Core.DependencyResolution;
using Microsoft.Python.Analysis.Core.Interpreter;
@@ -43,7 +42,7 @@ public static CompletionResult TryGetCompletions(ImportStatement import, Complet
if (name != null && context.Position >= name.StartIndex) {
if (context.Position > name.EndIndex && name.EndIndex > name.StartIndex) {
var applicableSpan = context.GetApplicableSpanFromLastToken(import);
- return new CompletionResult(new []{ CompletionItemSource.AsKeyword }, applicableSpan);
+ return new CompletionResult(new[] { CompletionItemSource.AsKeyword }, applicableSpan);
}
if (name.Names.Count == 0 || name.Names[0].EndIndex >= context.Position) {
@@ -62,7 +61,7 @@ public static CompletionResult TryGetCompletions(ImportStatement import, Complet
public static CompletionResult GetCompletionsInFromImport(FromImportStatement fromImport, CompletionContext context) {
// No more completions after '*', ever!
- if (fromImport.Names != null && fromImport.Names.Any(n => n?.Name == "*" && context.Position > n.EndIndex)) {
+ if (fromImport.Names.Any(n => n?.Name == "*" && context.Position > n.EndIndex)) {
return CompletionResult.Empty;
}
@@ -164,16 +163,15 @@ private static CompletionResult GetResultFromImportSearch(IImportSearchResult im
default:
return CompletionResult.Empty;
}
-
+
var completions = new List();
if (prependStar) {
completions.Add(CompletionItemSource.Star);
}
+ var memberNames = (module?.GetMemberNames().Where(n => !string.IsNullOrEmpty(n)) ?? Enumerable.Empty()).ToHashSet();
if (module != null) {
- completions.AddRange(module.GetMemberNames()
- .Where(n => !string.IsNullOrEmpty(n))
- .Select(n => context.ItemSource.CreateCompletionItem(n, module.GetMember(n))));
+ completions.AddRange(memberNames.Select(n => context.ItemSource.CreateCompletionItem(n, module.GetMember(n))));
}
if (importSearchResult is IImportChildrenSource children) {
@@ -182,14 +180,19 @@ private static CompletionResult GetResultFromImportSearch(IImportSearchResult im
continue;
}
+ string name = null;
switch (imports) {
case ImplicitPackageImport packageImport:
- completions.Add(CompletionItemSource.CreateCompletionItem(packageImport.Name, CompletionItemKind.Module));
+ name = packageImport.Name;
break;
case ModuleImport moduleImport when !moduleImport.ModulePath.PathEquals(document.FilePath):
- completions.Add(CompletionItemSource.CreateCompletionItem(moduleImport.Name, CompletionItemKind.Module));
+ name = moduleImport.Name;
break;
}
+
+ if (name != null && !memberNames.Contains(name)) {
+ completions.Add(CompletionItemSource.CreateCompletionItem(name, CompletionItemKind.Module));
+ }
}
}
diff --git a/src/LanguageServer/Impl/Implementation/Server.cs b/src/LanguageServer/Impl/Implementation/Server.cs
index 01c643ea9..4a553a2f8 100644
--- a/src/LanguageServer/Impl/Implementation/Server.cs
+++ b/src/LanguageServer/Impl/Implementation/Server.cs
@@ -168,7 +168,7 @@ public async Task InitializedAsync(InitializedParams @params, CancellationToken
_completionSource = new CompletionSource(
ChooseDocumentationSource(textDocCaps?.completion?.completionItem?.documentationFormat),
- Settings.completion
+ Settings.completion, Services
);
_hoverSource = new HoverSource(
diff --git a/src/LanguageServer/Impl/LanguageServer.Lifetime.cs b/src/LanguageServer/Impl/LanguageServer.Lifetime.cs
index f09b44db4..3412109cc 100644
--- a/src/LanguageServer/Impl/LanguageServer.Lifetime.cs
+++ b/src/LanguageServer/Impl/LanguageServer.Lifetime.cs
@@ -14,7 +14,6 @@
// permissions and limitations under the License.
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
diff --git a/src/LanguageServer/Impl/LanguageServer.cs b/src/LanguageServer/Impl/LanguageServer.cs
index ca4d1e962..9c838b868 100644
--- a/src/LanguageServer/Impl/LanguageServer.cs
+++ b/src/LanguageServer/Impl/LanguageServer.cs
@@ -15,7 +15,6 @@
// permissions and limitations under the License.
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
@@ -32,7 +31,6 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StreamJsonRpc;
-using Range = Microsoft.Python.Core.Text.Range;
namespace Microsoft.Python.LanguageServer.Implementation {
///
diff --git a/src/LanguageServer/Test/CompletionTests.cs b/src/LanguageServer/Test/CompletionTests.cs
index 2839faca8..978aa99de 100644
--- a/src/LanguageServer/Test/CompletionTests.cs
+++ b/src/LanguageServer/Test/CompletionTests.cs
@@ -59,7 +59,7 @@ def method(self):
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(8, 1));
comps.Should().HaveLabels("C", "x", "y", "while", "for");
}
@@ -71,7 +71,7 @@ public async Task StringMembers() {
x.
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(3, 3));
comps.Should().HaveLabels(@"isupper", @"capitalize", @"split");
}
@@ -83,7 +83,7 @@ import datetime
datetime.datetime.
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(3, 19));
comps.Should().HaveLabels("now", @"tzinfo", @"ctime");
}
@@ -98,7 +98,7 @@ def method1(self): pass
ABCDE.me
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(5, 4));
comps.Should().HaveLabels(@"ABCDE");
@@ -116,7 +116,7 @@ class oar(list):
pass
";
var analysis = await GetAnalysisAsync(code, version);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 9));
result.Should().HaveItem("append")
@@ -131,7 +131,7 @@ class Test():
def __
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 10));
result.Should().HaveItem("__init__")
@@ -149,7 +149,7 @@ class oar(list):
pass
";
var analysis = await GetAnalysisAsync(code, version);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 9));
result.Should().HaveItem("append")
@@ -168,7 +168,7 @@ class Test(A):
def __
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(7, 10));
result.Should().HaveItem("__init__")
@@ -192,7 +192,7 @@ def fob(self):
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(4, 8));
result.Should().HaveItem("a");
}
@@ -209,7 +209,7 @@ def oar(self, a):
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(4, 8));
result.Should().HaveItem("a");
}
@@ -231,7 +231,7 @@ def oar(self): pass
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(11, 3));
result.Should().NotContainLabels("fob");
result.Should().HaveLabels("oar");
@@ -250,7 +250,7 @@ class B(A):
def f";
var analysis = await GetAnalysisAsync(code, is3x ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(7, 10));
result.Should()
@@ -265,13 +265,13 @@ public async Task InRaise(bool is3X) {
var version = is3X ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X;
var analysis = await GetAnalysisAsync("raise ", version);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 7));
result.Should().HaveInsertTexts("Exception", "ValueError").And.NotContainInsertTexts("def", "abs");
if (is3X) {
analysis = await GetAnalysisAsync("raise Exception from ", PythonVersions.LatestAvailable3X);
- cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
result = cs.GetCompletions(analysis, new SourceLocation(1, 7));
result.Should().HaveInsertTexts("Exception", "ValueError").And.NotContainInsertTexts("def", "abs");
@@ -301,7 +301,7 @@ public async Task InRaise(bool is3X) {
[TestMethod, Priority(0)]
public async Task InExcept() {
var analysis = await GetAnalysisAsync("try:\n pass\nexcept ");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 8));
result.Should().HaveInsertTexts("Exception", "ValueError").And.NotContainInsertTexts("def", "abs");
@@ -342,7 +342,7 @@ public async Task AfterDot() {
x
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 3));
result.Should().HaveLabels("real", @"imag").And.NotContainLabels("abs");
@@ -369,7 +369,7 @@ public async Task AfterDot() {
[TestMethod, Priority(0)]
public async Task AfterAssign() {
var analysis = await GetAnalysisAsync("x = x\ny = ");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(2, 4));
result.Should().HaveLabels("x", "abs");
@@ -389,7 +389,7 @@ def test_exception(self):
self.assertRaises(TypeError).
";
var analysis = await GetAnalysisAsync(code, is3x ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(5, 38));
result.Should().HaveInsertTexts("exception");
@@ -401,7 +401,7 @@ public async Task WithWhitespaceAroundDot() {
sys . version
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(2, 7));
result.Should().HaveLabels("argv");
@@ -410,7 +410,7 @@ sys . version
[TestMethod, Priority(0)]
public async Task MarkupKindValid() {
var analysis = await GetAnalysisAsync("import sys\nsys.\n");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(2, 5));
result.Completions?.Select(i => i.documentation?.kind).ExcludeDefault()
@@ -427,7 +427,7 @@ from typing import NewType
foo.
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(6, 5));
result.Should().HaveLabels("clear", "copy", "items", "keys", "update", "values");
@@ -444,7 +444,7 @@ def func(a: List[str]):
pass
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(5, 7));
result.Should().HaveLabels("clear", "copy", "count", "index", "remove", "reverse");
@@ -464,7 +464,7 @@ def func(a: Dict[int, str]):
pass
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(5, 7));
result.Should().HaveLabels("keys", "values");
@@ -494,7 +494,7 @@ def get(self) -> _T:
y = boxedstr.
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(14, 14));
result.Should().HaveItem("get").Which.Should().HaveDocumentation("Box.get() -> int");
@@ -526,7 +526,7 @@ def get(self) -> _T:
y = boxedstr.
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(14, 14));
result.Should().HaveLabels("append", "index");
@@ -555,7 +555,7 @@ def fob(self, x):
def baz(self): pass
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var completionInD = cs.GetCompletions(analysis, new SourceLocation(3, 5));
var completionInOar = cs.GetCompletions(analysis, new SourceLocation(5, 9));
@@ -581,7 +581,7 @@ def abc(self):
x.abc()
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var objectMemberNames = analysis.Document.Interpreter.GetBuiltinType(BuiltinTypeId.Object).GetMemberNames();
var completion = cs.GetCompletions(analysis, new SourceLocation(7, 1));
@@ -598,7 +598,7 @@ public async Task InFunctionDefinition(bool is3X) {
var version = is3X ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X;
var analysis = await GetAnalysisAsync("def f(a, b:int, c=2, d:float=None): pass", version);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 5));
result.Should().HaveNoCompletion();
@@ -632,7 +632,7 @@ public async Task InFunctionDefinition(bool is3X) {
[TestMethod, Priority(0)]
public async Task InFunctionDefinition_2X() {
var analysis = await GetAnalysisAsync("@dec" + Environment.NewLine + "def f(): pass", PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 1));
result.Should().HaveLabels("any");
@@ -656,7 +656,7 @@ public async Task InFunctionDefinition_2X() {
[TestMethod, Priority(0)]
public async Task InFunctionDefinition_3X() {
var analysis = await GetAnalysisAsync("@dec" + Environment.NewLine + "async def f(): pass", PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 1));
result.Should().HaveLabels("any");
@@ -684,7 +684,7 @@ public async Task InClassDefinition(bool is3x) {
var version = is3x ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X;
var analysis = await GetAnalysisAsync("class C(object, parameter=MC): pass", version);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 8));
result.Should().HaveNoCompletion();
@@ -726,7 +726,7 @@ public async Task InClassDefinition(bool is3x) {
[TestMethod, Priority(0)]
public async Task InWithStatement() {
var analysis = await GetAnalysisAsync("with x as y, z as w: pass");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 6));
result.Should().HaveAnyCompletions();
@@ -780,7 +780,7 @@ public async Task ImportInPackage() {
var analysis2 = await module2.GetAnalysisAsync(-1);
var analysis3 = await module3.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis1, new SourceLocation(1, 16));
result.Should().OnlyHaveLabels("module2", "sub_package");
@@ -801,7 +801,7 @@ public async Task InImport() {
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(2, 7));
result.Should().HaveLabels("from", "import", "abs", "dir").And.NotContainLabels("abc");
@@ -887,7 +887,7 @@ def i(): pass
def
pass";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 9));
result.Should().HaveNoCompletion();
@@ -905,7 +905,7 @@ def i(): pass
public async Task NoCompletionInEllipsis(bool is2x) {
const string code = "...";
var analysis = await GetAnalysisAsync(code, is2x ? PythonVersions.LatestAvailable2X : PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 4));
result.Should().HaveNoCompletion();
@@ -917,7 +917,7 @@ public async Task NoCompletionInEllipsis(bool is2x) {
[DataTestMethod, Priority(0)]
public async Task NoCompletionInString(bool is2x) {
var analysis = await GetAnalysisAsync("\"str.\"", is2x ? PythonVersions.LatestAvailable2X : PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 6));
result.Should().HaveNoCompletion();
}
@@ -925,7 +925,7 @@ public async Task NoCompletionInString(bool is2x) {
[TestMethod, Priority(0)]
public async Task NoCompletionInOpenString() {
var analysis = await GetAnalysisAsync("'''.");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 5));
result.Should().HaveNoCompletion();
}
@@ -936,7 +936,7 @@ public async Task NoCompletionInOpenString() {
[DataTestMethod, Priority(0)]
public async Task NoCompletionInFStringConstant(string openFString) {
var analysis = await GetAnalysisAsync(openFString);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 5));
result.Should().HaveNoCompletion();
}
@@ -944,7 +944,7 @@ public async Task NoCompletionInFStringConstant(string openFString) {
[TestMethod, Priority(0)]
public async Task NoCompletionBadImportExpression() {
var analysis = await GetAnalysisAsync("import os,.");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
cs.GetCompletions(analysis, new SourceLocation(1, 12)); // Should not crash.
}
@@ -952,7 +952,7 @@ public async Task NoCompletionBadImportExpression() {
public async Task NoCompletionInComment() {
var analysis = await GetAnalysisAsync("x = 1 #str. more text");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 12));
result.Should().HaveNoCompletion();
}
@@ -966,7 +966,7 @@ import os
os.
";
var analysis = await GetAnalysisAsync(code, is3x ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 4));
result.Should().HaveLabels("path", @"devnull", "SEEK_SET", @"curdir");
@@ -981,7 +981,7 @@ import os
os.path.
";
var analysis = await GetAnalysisAsync(code, is3x ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 9));
result.Should().HaveLabels("split", @"getsize", @"islink", @"abspath");
@@ -991,7 +991,7 @@ import os
public async Task FromDotInRoot() {
const string code = "from .";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 7));
result.Should().HaveNoCompletion();
@@ -1011,7 +1011,7 @@ public async Task FromDotInRootWithInitPy() {
var analysis = await module1.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 7));
result.Should().OnlyHaveLabels("__dict__", "__file__", "__doc__", "__package__", "__debug__", "__name__", "__path__", "__spec__");
}
@@ -1034,7 +1034,7 @@ public async Task FromDotInExplicitPackage() {
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await module.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 7));
result.Should().HaveLabels("module2", "sub_package", "answer");
@@ -1057,7 +1057,7 @@ public async Task FromPartialName() {
await module.GetAnalysisAsync(-1);
var analysis1 = await module1.GetAnalysisAsync(-1);
var analysis2 = await module2.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis1, new SourceLocation(1, 8));
result.Should().HaveLabels("package").And.NotContainLabels("module2", "sub_package", "answer");
@@ -1079,12 +1079,31 @@ public async Task FromDotInImplicitPackage() {
rdt.OpenDocument(module3, string.Empty);
var analysis = await module.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 7));
result.Should().OnlyHaveLabels("module2", "sub_package");
}
+ [TestMethod, Priority(0)]
+ public async Task SubmoduleMember() {
+ var appUri = TestData.GetTestSpecificUri("app.py");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("package", "__init__.py"), "from . import m1\nfrom . import m2\nx = 1");
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("package", "m1", "__init__.py"), string.Empty);
+ await TestData.CreateTestSpecificFileAsync(Path.Combine("package", "m2", "__init__.py"), string.Empty);
+
+ await CreateServicesAsync(PythonVersions.LatestAvailable3X);
+ var rdt = Services.GetService();
+ var doc = rdt.OpenDocument(appUri, "import package\npackage.");
+
+ await Services.GetService().WaitForCompleteAnalysisAsync();
+ var analysis = await doc.GetAnalysisAsync(Timeout.Infinite);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
+
+ var result = cs.GetCompletions(analysis, new SourceLocation(2, 9));
+ result.Should().HaveLabels("m1", "m2", "x");
+ }
+
[DataRow(false)]
[DataRow(true)]
[DataTestMethod, Priority(0)]
@@ -1094,7 +1113,7 @@ from os.path import exists as EX
E
";
var analysis = await GetAnalysisAsync(code, is3x ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 2));
result.Should().HaveLabels("EX");
@@ -1107,7 +1126,7 @@ from os.path import exists as EX
public async Task NoDuplicateMembers() {
const string code = @"import sy";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, 10));
result.Completions.Count(c => c.label.EqualsOrdinal(@"sys")).Should().Be(1);
@@ -1124,7 +1143,7 @@ class A: ...
a.
";
var analysis = await GetAnalysisAsync(code, is3x ? PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var extraMembers = new[] { "mro", "__dict__", @"__weakref__" };
var result = cs.GetCompletions(analysis, new SourceLocation(4, 3));
if (is3x) {
@@ -1151,7 +1170,7 @@ def main(req: func.HttpRequest) -> func.HttpResponse:
$"'azure.functions' package is not installed for Python {ver}, see https://github.com/Microsoft/python-language-server/issues/462");
}
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(5, 23));
result.Should().HaveLabels("get");
result.Completions.First(x => x.label == "get").Should().HaveDocumentation("dict.get*");
@@ -1163,7 +1182,7 @@ public async Task InForEnumeration() {
for a, b in x:
");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(3, 4));
result.Should().HaveLabels("a", "b");
}
@@ -1176,7 +1195,7 @@ public async Task NoCompletionForCurrentModuleName(bool empty) {
var code = empty ? string.Empty : $"{Path.GetFileNameWithoutExtension(modulePath)}.";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X, null, modulePath);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(1, code.Length + 1));
result.Should().NotContainLabels(analysis.Document.Name);
}
@@ -1194,7 +1213,7 @@ import sys
var analysis = await GetDocumentAnalysisAsync(doc);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var completions = cs.GetCompletions(analysis, new SourceLocation(3, 5));
completions.Should().HaveLabels("argv", "path", "exit");
}
@@ -1206,7 +1225,7 @@ def func():
aaa = 1
a";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(4, 2));
result.Completions.Select(c => c.label).Should().NotContain("aaa");
@@ -1225,7 +1244,7 @@ def func(self):
A().
";
var analysis = await GetAnalysisAsync(code);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var result = cs.GetCompletions(analysis, new SourceLocation(7, 14));
result.Completions.Select(c => c.label).Should().Contain("__x").And.NotContain("_A__x");
@@ -1251,7 +1270,7 @@ def test(x: Foo = func()):
x.
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(13, 7));
comps.Should().HaveLabels("name", "z");
}
@@ -1262,7 +1281,7 @@ public async Task AddBrackets() {
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
ServerSettings.completion.addBrackets = true;
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(1, 5));
var print = comps.Completions.FirstOrDefault(x => x.label == "print");
@@ -1294,7 +1313,7 @@ def method2(self):
";
var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(11, 21));
var names = comps.Completions.Select(c => c.label);
@@ -1317,7 +1336,7 @@ public async Task FromImportPackageNoInitPy() {
await Services.GetService().WaitForCompleteAnalysisAsync();
var analysis = await doc.GetAnalysisAsync(Timeout.Infinite);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(1, 18));
var names = comps.Completions.Select(c => c.label);
names.Should().Contain(new[] { "sub1" });
diff --git a/src/LanguageServer/Test/ImportsTests.cs b/src/LanguageServer/Test/ImportsTests.cs
index fd3b4824b..b114e05ff 100644
--- a/src/LanguageServer/Test/ImportsTests.cs
+++ b/src/LanguageServer/Test/ImportsTests.cs
@@ -71,7 +71,7 @@ import projectB.foo.baz
var doc = rdt.OpenDocument(new Uri(appPath), appCode, appPath);
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(7, 10));
comps.Should().HaveLabels("foo");
@@ -117,7 +117,7 @@ from projectB.foo import baz
var doc = rdt.OpenDocument(new Uri(appPath), appCode, appPath);
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(8, 10));
comps.Should().HaveLabels("foo");
@@ -154,7 +154,7 @@ public async Task SysModuleChain() {
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await doc1.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(2, 5));
comps.Should().HaveLabels("VALUE");
}
@@ -176,7 +176,7 @@ await TestData.CreateTestSpecificFileAsync("module2.py", @"import sys
await Services.GetService().WaitForCompleteAnalysisAsync();
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(2, 5));
comps.Should().HaveLabels("VALUE");
}
@@ -202,7 +202,7 @@ public async Task UncSearchPaths() {
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(1, 21));
comps.Should().HaveLabels("module1", "module2");
@@ -257,7 +257,7 @@ def method2():
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(2, 6));
comps.Should().HaveLabels("A").And.NotContainLabels("B");
@@ -296,7 +296,7 @@ import package.sub_package.module2
var doc = rdt.OpenDocument(new Uri(appPath), appCode);
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(5, 9));
comps.Should().OnlyHaveLabels("sub_package");
@@ -333,7 +333,7 @@ import package.module.submodule as submodule
var doc = rdt.OpenDocument(appUri, appCode);
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(4, 8));
comps.Should().HaveLabels("Y").And.NotContainLabels("X");
@@ -364,7 +364,7 @@ from package.module import submodule
var doc = rdt.OpenDocument(appUri, appCode);
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(4, 8));
comps.Should().HaveLabels("Y").And.NotContainLabels("X");
@@ -395,7 +395,7 @@ from .sub_package.module import submodule
var doc = rdt.OpenDocument(new Uri(appPath), appCode);
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(4, 8));
comps.Should().HaveLabels("Y").And.NotContainLabels("X");
@@ -464,7 +464,7 @@ from module3 import A3
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await app.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(10, 4));
comps.Should().HaveLabels("M2");
@@ -478,7 +478,7 @@ from module3 import A3
[TestMethod, Priority(0)]
public async Task TypingModule() {
var analysis = await GetAnalysisAsync(@"from typing import ");
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(1, 20));
comps.Should().HaveLabels("TypeVar", "List", "Dict", "Union");
}
@@ -503,7 +503,7 @@ public async Task RelativeImportsFromParent() {
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await module2.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(2, 9));
comps.Should().HaveLabels("X");
}
@@ -528,7 +528,7 @@ public async Task FromImport_ModuleAffectsPackage(string appCodeImport) {
var doc = rdt.OpenDocument(new Uri(appPath), appCode1);
var analysis = await doc.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(2, 13));
comps.Should().OnlyHaveLabels("module");
@@ -581,7 +581,7 @@ from module1 import *
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await app.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(4, 5));
comps.Should().HaveLabels("foo");
@@ -644,7 +644,7 @@ from module1 import *
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await app.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(4, 5));
comps.Should().HaveLabels("foo");
@@ -707,7 +707,7 @@ from module1 import *
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await app.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(4, 5));
comps.Should().HaveLabels("foo");
@@ -751,7 +751,7 @@ from module1 import _B as B
await analyzer.WaitForCompleteAnalysisAsync();
var analysis = await app.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(5, 5));
comps.Should().HaveLabels("foo");
@@ -790,7 +790,7 @@ public async Task Python2XRelativeImportInRoot() {
var analysis = await app.GetAnalysisAsync(-1);
var analysisInPackage = await appInPackage.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(2, 8));
comps.Should().HaveLabels("X");
@@ -824,7 +824,7 @@ import module2
var app = rdt.OpenDocument(appUri, appContent);
var analysis = await app.GetAnalysisAsync(-1);
- var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
+ var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion, Services);
var comps = cs.GetCompletions(analysis, new SourceLocation(3, 9));
comps.Should().HaveLabels("X");