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

Commit 84d44ee

Browse files
jakebaileyMikhail Arkhipov
authored and
Mikhail Arkhipov
committed
Look into PATH for python if not provided in initialization opt… (#1949)
* Look into PATH for python if not provided in initialization options * Improve styling (cherry picked from commit d3c6cfb)
1 parent 573d3db commit 84d44ee

File tree

4 files changed

+83
-2
lines changed

4 files changed

+83
-2
lines changed

src/Core/Impl/IO/PathUtils.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,5 +521,30 @@ public static string NormalizePath(string path) {
521521
}
522522

523523
public static string NormalizePathAndTrim(string path) => TrimEndSeparator(NormalizePath(path));
524+
525+
public static string LookPath(IFileSystem fs, string exeName) {
526+
var path = Environment.GetEnvironmentVariable("PATH");
527+
if (string.IsNullOrWhiteSpace(path)) {
528+
return null;
529+
}
530+
531+
foreach (var p in path.Split(Path.PathSeparator)) {
532+
var x = Path.Combine(p, exeName);
533+
534+
if (IsWindows) {
535+
x += ".exe"; // TODO: other extensions?
536+
}
537+
538+
if (!fs.FileExists(x)) {
539+
continue;
540+
}
541+
542+
// TODO: check executable on non-Windows platforms.
543+
544+
return x;
545+
}
546+
547+
return null;
548+
}
524549
}
525550
}

src/LanguageServer/Impl/Implementation/Server.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using System.Diagnostics;
1919
using System.Linq;
2020
using System.Reflection;
21+
using System.Text;
2122
using System.Threading;
2223
using System.Threading.Tasks;
2324
using Microsoft.Python.Analysis;
@@ -138,10 +139,24 @@ public async Task InitializedAsync(InitializedParams @params, CancellationToken
138139
_services.AddService(new RunningDocumentTable(_services));
139140
_rdt = _services.GetService<IRunningDocumentTable>();
140141

141-
Version.TryParse(initializationOptions?.interpreter.properties?.Version, out var version);
142+
var interpeterPath = initializationOptions?.interpreter.properties?.InterpreterPath;
143+
Version version = null;
144+
145+
if (!string.IsNullOrWhiteSpace(interpeterPath)) {
146+
Version.TryParse(initializationOptions?.interpreter.properties?.Version, out version);
147+
} else {
148+
var fs = _services.GetService<IFileSystem>();
149+
var exePath = PathUtils.LookPath(fs, "python");
150+
if (exePath != null && TryGetPythonVersion(exePath, out version)) {
151+
_log?.Log(TraceEventType.Information, Resources.UsingPythonFromPATH);
152+
interpeterPath = exePath;
153+
} else {
154+
interpeterPath = null;
155+
}
156+
}
142157

143158
var configuration = new InterpreterConfiguration(
144-
interpreterPath: initializationOptions?.interpreter.properties?.InterpreterPath,
159+
interpreterPath: interpeterPath,
145160
version: version
146161
);
147162
_services.AddService(new ModuleDatabase(_services));
@@ -286,6 +301,35 @@ private void ResetAnalyzer() {
286301
_log?.Log(TraceEventType.Information, Resources.AnalysisRestarted);
287302
}).DoNotWait();
288303
}
304+
305+
private bool TryGetPythonVersion(string exePath, out Version version) {
306+
try {
307+
using var process = new Process {
308+
StartInfo = new ProcessStartInfo {
309+
FileName = exePath,
310+
Arguments = "-c \"import sys; print('{}.{}.{}'.format(*sys.version_info))\"",
311+
UseShellExecute = false,
312+
ErrorDialog = false,
313+
CreateNoWindow = true,
314+
StandardOutputEncoding = Encoding.UTF8,
315+
RedirectStandardInput = true,
316+
RedirectStandardOutput = true,
317+
RedirectStandardError = true
318+
}
319+
};
320+
321+
process.ErrorDataReceived += (s, e) => { };
322+
process.Start();
323+
process.BeginErrorReadLine();
324+
325+
var output = process.StandardOutput.ReadToEnd();
326+
327+
return Version.TryParse(output, out version);
328+
} catch (Exception ex) when (!ex.IsCriticalException()) { }
329+
330+
version = null;
331+
return false;
332+
}
289333
#endregion
290334
}
291335
}

src/LanguageServer/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/LanguageServer/Impl/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@
159159
<data name="RenameVariable_CannotRename" xml:space="preserve">
160160
<value>Cannot rename</value>
161161
</data>
162+
<data name="UsingPythonFromPATH" xml:space="preserve">
163+
<value>No interpreter specified, using Python from PATH.</value>
164+
</data>
162165
<data name="WorkspaceRoot" xml:space="preserve">
163166
<value>Workspace root: {0}</value>
164167
</data>

0 commit comments

Comments
 (0)