Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit 446cb26

Browse files
authored
Clean up initialization configuration (#793)
For #720. Fixes #608. Fixes #678. This is the first set of configuration cleanup changes. This is a backwards compatible change, and will work on the existing build of the extension. A future PR will modify how searchPaths and get_search_paths.py work.
1 parent e58468c commit 446cb26

File tree

8 files changed

+99
-81
lines changed

8 files changed

+99
-81
lines changed

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,49 @@ Primary clients are [Python Extension to VS Code](https://github.com/Microsoft/v
77
[Building Language Server](https://github.com/Microsoft/python-language-server/blob/master/CONTRIBUTING.md)
88

99
Feel free to file issues or ask questions on our [issue tracker](https://github.com/Microsoft/python-language-server/issues), and we welcome code contributions.
10+
11+
12+
## Linting options (diagnostics)
13+
14+
The language server implements diagnostics (or linting), which runs on user code.
15+
The following diagnostics are supported:
16+
17+
| Code | Description |
18+
| - | - |
19+
| `too-many-function-arguments` | Too many arguments have been provided to a function call. |
20+
| `too-many-positional-arguments-before-star` | Too many arguments have been provided before a starred argument. |
21+
| `positional-argument-after-keyword` | A positional argument has been provided after a keyword argument. |
22+
| `unknown-parameter-name` | The keyword argument name provided is unknown. |
23+
| `parameter-already-specified` | A argument with this name has already been specified. |
24+
| `parameter-missing` | A required positional argument is missing. |
25+
| `unresolved-import` | An import cannot be resolved, and may be missing. |
26+
| `undefined-variable` | A variable has used that has not yet been defined. |
27+
28+
[A full list can be seen in the source code.](src\Analysis\Impl\Diagnostics\ErrorCodes.cs)
29+
30+
Linting can be controlled via the user configuration. In VS Code, this is `settings.json`, but other
31+
clients would send this via `workspace/didChangeConfiguration`.
32+
33+
If `python.linting.enabled` is set to `false` in the user configuration, then no diagnostics
34+
will be collected other than syntax errors and unresolved imports.
35+
36+
To control the visibility and severity of the diagnotics, there are a number of lists
37+
that can be set in the user configuration which make use of each diagnostic's error code.
38+
39+
| Setting | Description |
40+
| - | - |
41+
| `python.analysis.errors` | Diagnostics which should be shown as errors. |
42+
| `python.analysis.warnings` | Diagnostics which should be shown as warnings. |
43+
| `python.analysis.info` | Diagnostics which should be shown as informational. |
44+
| `python.analysis.errors` | Diagnotics which should not be shown at all. |
45+
46+
An example of a user configuration which sets these options:
47+
48+
```json
49+
{
50+
"python.analysis.errors": ["undefined-variable"],
51+
"python.analysis.warnings": ["unknown-parameter-name"],
52+
"python.analysis.info": ["unresolved-import"],
53+
"python.analysis.disabled": ["too-many-function-arguments", "parameter-missing"],
54+
}
55+
```

src/Analysis/Core/Impl/Interpreter/InterpreterConfiguration.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public sealed class InterpreterConfiguration : IEquatable<InterpreterConfigurati
3030
public InterpreterConfiguration(
3131
string id,
3232
string description,
33-
string pythonExePath = null,
33+
string interpreterPath = null,
3434
string pathVar = "",
3535
string libPath = null,
3636
string sitePackagesPath = null,
@@ -41,7 +41,7 @@ public InterpreterConfiguration(
4141
) {
4242
Id = id;
4343
_description = description ?? string.Empty;
44-
InterpreterPath = pythonExePath;
44+
InterpreterPath = interpreterPath;
4545
PathEnvironmentVariable = pathVar;
4646
Architecture = architecture ?? InterpreterArchitecture.Unknown;
4747
Version = version ?? new Version();

src/LanguageServer/Impl/Implementation/Server.cs

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ public sealed partial class Server : IDisposable {
4747
private ILogger _log;
4848
private IIndexManager _indexManager;
4949

50-
public static InformationDisplayOptions DisplayOptions { get; private set; } = new InformationDisplayOptions {
51-
preferredFormat = MarkupKind.PlainText,
52-
trimDocumentationLines = true,
53-
maxDocumentationLineLength = 100,
54-
trimDocumentationText = true,
55-
maxDocumentationTextLength = 1024,
56-
maxDocumentationLines = 100
57-
};
58-
5950
public Server(IServiceManager services) {
6051
_services = services;
6152

@@ -102,10 +93,6 @@ public async Task<InitializeResult> InitializeAsync(InitializeParams @params, Ca
10293
_clientCaps = @params.capabilities;
10394
_log = _services.GetService<ILogger>();
10495

105-
if (@params.initializationOptions.displayOptions != null) {
106-
DisplayOptions = @params.initializationOptions.displayOptions;
107-
}
108-
10996
_services.AddService(new DiagnosticsService(_services));
11097

11198
var analyzer = new PythonAnalyzer(_services);
@@ -116,9 +103,19 @@ public async Task<InitializeResult> InitializeAsync(InitializeParams @params, Ca
116103

117104
// TODO: multi-root workspaces.
118105
var rootDir = @params.rootUri != null ? @params.rootUri.ToAbsolutePath() : PathUtils.NormalizePath(@params.rootPath);
119-
var configuration = InterpreterConfiguration.FromDictionary(@params.initializationOptions.interpreter.properties);
120-
configuration.SearchPaths = @params.initializationOptions.searchPaths.Select(p => p.Split(';', StringSplitOptions.RemoveEmptyEntries)).SelectMany().ToList();
121-
configuration.TypeshedPath = @params.initializationOptions.typeStubSearchPaths.FirstOrDefault();
106+
107+
Version.TryParse(@params.initializationOptions.interpreter.properties?.Version, out var version);
108+
109+
var configuration = new InterpreterConfiguration(null, null,
110+
interpreterPath: @params.initializationOptions.interpreter.properties?.InterpreterPath,
111+
moduleCachePath: @params.initializationOptions.interpreter.properties?.DatabasePath,
112+
version: version
113+
) {
114+
// TODO: Remove this split once the extension is updated and no longer passes the interpreter search paths directly.
115+
// This is generally harmless to keep around.
116+
SearchPaths = @params.initializationOptions.searchPaths.Select(p => p.Split(new[] { ';', ':' }, StringSplitOptions.RemoveEmptyEntries)).SelectMany().ToList(),
117+
TypeshedPath = @params.initializationOptions.typeStubSearchPaths.FirstOrDefault()
118+
};
122119

123120
_interpreter = await PythonInterpreter.CreateAsync(configuration, rootDir, _services, cancellationToken);
124121
_services.AddService(_interpreter);
@@ -133,18 +130,18 @@ public async Task<InitializeResult> InitializeAsync(InitializeParams @params, Ca
133130

134131
DisplayStartupInfo();
135132

136-
// TODO: Pass different documentation sources to completion/hover/signature
137-
// based on client capabilities.
138-
IDocumentationSource ds;
139-
if (DisplayOptions.preferredFormat == MarkupKind.Markdown) {
140-
ds = new MarkdownDocumentationSource();
141-
} else {
142-
ds = new PlainTextDocumentationSource();
143-
}
133+
_completionSource = new CompletionSource(
134+
ChooseDocumentationSource(_clientCaps?.textDocument?.completion?.completionItem?.documentationFormat),
135+
Settings.completion
136+
);
137+
138+
_hoverSource = new HoverSource(
139+
ChooseDocumentationSource(_clientCaps?.textDocument?.hover?.contentFormat)
140+
);
144141

145-
_completionSource = new CompletionSource(ds, Settings.completion);
146-
_hoverSource = new HoverSource(ds);
147-
_signatureSource = new SignatureSource(ds);
142+
_signatureSource = new SignatureSource(
143+
ChooseDocumentationSource(_clientCaps?.textDocument?.signatureHelp?.signatureInformation?.documentationFormat)
144+
);
148145

149146
return GetInitializeResult();
150147
}
@@ -198,6 +195,23 @@ private bool HandleConfigurationChanges(ServerSettings newSettings) {
198195

199196
return false;
200197
}
198+
199+
private IDocumentationSource ChooseDocumentationSource(string[] kinds) {
200+
if (kinds == null) {
201+
return new PlainTextDocumentationSource();
202+
}
203+
204+
foreach (var k in kinds) {
205+
switch (k) {
206+
case MarkupKind.Markdown:
207+
return new MarkdownDocumentationSource();
208+
case MarkupKind.PlainText:
209+
return new PlainTextDocumentationSource();
210+
}
211+
}
212+
213+
return new PlainTextDocumentationSource();
214+
}
201215
#endregion
202216

203217
public void NotifyPackagesChanged(CancellationToken cancellationToken) {

src/LanguageServer/Impl/Protocol/Classes.cs

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,12 @@ public sealed class DocumentFilter {
130130
public sealed class PythonInitializationOptions {
131131
[Serializable]
132132
public struct Interpreter {
133-
/// <summary>
134-
/// The serialized info required to restore an interpreter factory
135-
/// </summary>
136-
public string assembly;
137-
public string typeName;
138-
public Dictionary<string, object> properties;
139-
140-
/// <summary>
141-
/// The x.y language version of the interpreter in case the factory
142-
/// cannot be restored.
143-
/// </summary>
144-
public string version;
133+
public sealed class InterpreterProperties {
134+
public string Version;
135+
public string InterpreterPath;
136+
public string DatabasePath;
137+
}
138+
public InterpreterProperties properties;
145139
}
146140
public Interpreter interpreter;
147141

@@ -155,11 +149,6 @@ public struct Interpreter {
155149
/// </summary>
156150
public string[] typeStubSearchPaths = Array.Empty<string>();
157151

158-
/// <summary>
159-
/// Controls tooltip display appearance. Different between VS and VS Code.
160-
/// </summary>
161-
public InformationDisplayOptions displayOptions = new InformationDisplayOptions();
162-
163152
/// <summary>
164153
/// Glob pattern of files and folders to exclude from loading
165154
/// into the Python analysis engine.
@@ -171,12 +160,6 @@ public struct Interpreter {
171160
/// should be loaded into the Python analysis engine.
172161
/// </summary>
173162
public string[] includeFiles = Array.Empty<string>();
174-
175-
/// <summary>
176-
/// Enables an even higher level of logging via the logMessage event.
177-
/// This will likely have a performance impact.
178-
/// </summary>
179-
public bool traceLogging;
180163
}
181164

182165
[Serializable]

src/LanguageServer/Impl/Protocol/InformationDisplayOptions.cs

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/Parsing/Test/PythonVersions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ private static InterpreterConfiguration GetJythonVersion(PythonLanguageVersion v
158158
return new InterpreterConfiguration(
159159
id: $"Global|Jython|{version.ToVersion()}",
160160
description: string.Format("Jython {0}", version.ToVersion()),
161-
pythonExePath: interpreter.FullName,
161+
interpreterPath: interpreter.FullName,
162162
version: version.ToVersion()
163163
);
164164
}

src/Parsing/Test/UnixPythonInstallPathResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ private InterpreterConfiguration GetConfiguration(string idPrefix, string python
9292
return new InterpreterConfiguration(
9393
id: $"{idPrefix}|{version}",
9494
description: $"{idPrefix} {version} ({architecture})",
95-
pythonExePath: pythonFilePath,
95+
interpreterPath: pythonFilePath,
9696
pathVar: pythonFilePath,
9797
libPath: libPath,
9898
sitePackagesPath: sitePackagesPath,

src/Parsing/Test/WindowsPythonInstallPathResolver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public InterpreterConfiguration GetIronPythonConfiguration(bool x64) {
5959
return new InterpreterConfiguration(
6060
id: x64 ? "IronPython|2.7-64" : "IronPython|2.7-32",
6161
description: string.Format("IronPython {0} 2.7", x64 ? "64-bit" : "32-bit"),
62-
pythonExePath: Path.Combine(installPath, exeName),
62+
interpreterPath: Path.Combine(installPath, exeName),
6363
libPath: Path.Combine(installPath, "Lib"),
6464
sitePackagesPath: Path.Combine(installPath, "Lib", "site-packages"),
6565
architecture: x64 ? InterpreterArchitecture.x64 : InterpreterArchitecture.x86,
@@ -193,7 +193,7 @@ InterpreterArchitecture assumedArchitecture
193193
return new InterpreterConfiguration(
194194
id: id,
195195
description: description,
196-
pythonExePath: exePath,
196+
interpreterPath: exePath,
197197
pathVar: pathVar,
198198
libPath: Path.Combine(prefixPath, "Lib"),
199199
sitePackagesPath: Path.Combine(prefixPath, "Lib", "site-packages"),

0 commit comments

Comments
 (0)