/// <summary>
        /// Gets the set of search paths by running the interpreter.
        /// </summary>
        /// <param name="interpreter">Path to the interpreter.</param>
        /// <param name="fs">File system services.</param>
        /// <param name="ps">Process services.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>A list of search paths for the interpreter.</returns>
        public static async Task <List <PythonLibraryPath> > GetSearchPathsFromInterpreterAsync(string interpreter, IFileSystem fs, IProcessServices ps, CancellationToken cancellationToken = default)
        {
            // sys.path will include the working directory, so we make an empty
            // path that we can filter out later
            var tempWorkingDir = IOPath.Combine(IOPath.GetTempPath(), IOPath.GetRandomFileName());

            fs.CreateDirectory(tempWorkingDir);
            if (!InstallPath.TryGetFile("get_search_paths.py", out var srcGetSearchPaths))
            {
                return(new List <PythonLibraryPath>());
            }
            var getSearchPaths = IOPath.Combine(tempWorkingDir, PathUtils.GetFileName(srcGetSearchPaths));

            File.Copy(srcGetSearchPaths, getSearchPaths);

            var startInfo = new ProcessStartInfo(
                interpreter,
                new[] { "-S", "-E", getSearchPaths }.AsQuotedArguments()
                )
            {
                WorkingDirectory       = tempWorkingDir,
                UseShellExecute        = false,
                ErrorDialog            = false,
                CreateNoWindow         = true,
                RedirectStandardInput  = true,
                RedirectStandardOutput = true
            };

            try {
                var output = await ps.ExecuteAndCaptureOutputAsync(startInfo, cancellationToken);

                return(output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Select(s => {
                    try {
                        var p = Parse(s);

                        if (PathUtils.PathStartsWith(p.Path, tempWorkingDir))
                        {
                            return null;
                        }

                        return p;
                    } catch (ArgumentException) {
                        Debug.Fail("Invalid search path: " + (s ?? "<null>"));
                        return null;
                    } catch (FormatException) {
                        Debug.Fail("Invalid format for search path: " + s);
                        return null;
                    }
                }).Where(p => p != null).ToList());
            } finally {
                fs.DeleteDirectory(tempWorkingDir, true);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the set of search paths by running the interpreter.
        /// </summary>
        /// <param name="interpreter">Path to the interpreter.</param>
        /// <param name="fs">File system services.</param>
        /// <param name="ps">Process services.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>A list of search paths for the interpreter.</returns>
        public static async Task <ImmutableArray <PythonLibraryPath> > GetSearchPathsFromInterpreterAsync(string interpreter, IFileSystem fs, IProcessServices ps, CancellationToken cancellationToken = default)
        {
            // sys.path will include the working directory, so we make an empty
            // path that we can filter out later
            var getSearchPathScript = Infrastructure.PythonToolsInstallPath.TryGetFile("get_search_paths.py");

            if (getSearchPathScript == null)
            {
                return(new ImmutableArray <PythonLibraryPath>());
            }

            var startInfo = new ProcessStartInfo(
                interpreter,
                new[] { "-S", "-E", getSearchPathScript }.AsQuotedArguments()
                )
            {
                WorkingDirectory       = IOPath.GetDirectoryName(getSearchPathScript),
                UseShellExecute        = false,
                ErrorDialog            = false,
                CreateNoWindow         = true,
                RedirectStandardInput  = true,
                RedirectStandardOutput = true
            };

            var output = await ps.ExecuteAndCaptureOutputAsync(startInfo, cancellationToken);

            return(output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                   .Select(s => {
                try {
                    return Parse(s);
                } catch (ArgumentException) {
                    Debug.Fail("Invalid search path: " + (s ?? "<null>"));
                    return null;
                } catch (FormatException) {
                    Debug.Fail("Invalid format for search path: " + s);
                    return null;
                }
            }).Where(p => p != null).ToImmutableArray());
        }