Ejemplo n.º 1
0
        public PythonInterpreterFactoryWithDatabase(
            InterpreterConfiguration config,
            bool watchLibraryForChanges
            )
        {
            _config = config;

            if (_config == null) {
                throw new ArgumentNullException("config");
            }

            // Avoid creating a interpreter with an unsupported version.
            // https://github.com/Microsoft/PTVS/issues/706
            try {
                var langVer = _config.Version.ToLanguageVersion();
            } catch (InvalidOperationException ex) {
                throw new ArgumentException(ex.Message, ex);
            }

            if (watchLibraryForChanges && Directory.Exists(_config.LibraryPath)) {
                _refreshIsCurrentTrigger = new Timer(RefreshIsCurrentTimer_Elapsed);

                _libWatcher = CreateLibraryWatcher();

                _isCheckingDatabase = true;
                _refreshIsCurrentTrigger.Change(1000, Timeout.Infinite);

                _verWatcher = CreateDatabaseVerWatcher();
                _verDirWatcher = CreateDatabaseDirectoryWatcher();
            }

            // Assume the database is valid if the directory exists, then switch
            // to invalid after we've checked.
            _isValid = Directory.Exists(DatabasePath);
        }
        public PythonInterpreterFactoryWithDatabase(
            Guid id,
            string description,
            InterpreterConfiguration config,
            bool watchLibraryForChanges
        ) {
            _description = description;
            _id = id;
            _config = config;

            if (watchLibraryForChanges && Directory.Exists(_config.LibraryPath)) {
                _refreshIsCurrentTrigger = new Timer(RefreshIsCurrentTimer_Elapsed);

                _libWatcher = CreateLibraryWatcher();

                _isCheckingDatabase = true;
                _refreshIsCurrentTrigger.Change(1000, Timeout.Infinite);

                _verWatcher = CreateDatabaseVerWatcher();
                _verDirWatcher = CreateDatabaseDirectoryWatcher();
            }

            // Assume the database is valid if the directory exists, then switch
            // to invalid after we've checked.
            _isValid = Directory.Exists(DatabasePath);
        }
Ejemplo n.º 3
0
 public PythonUwpInterpreterFactory(InterpreterConfiguration configuration) 
     : base(configuration, new InterpreterFactoryCreationOptions {
         PackageManager = BuiltInPackageManagers.Pip,
         DatabasePath = Path.Combine(configuration.PrefixPath, "completionDB"),
         WatchFileSystem = true
     }) {
 }
Ejemplo n.º 4
0
 public LaunchConfiguration(InterpreterConfiguration config, IDictionary<string, string> options = null)
 {
     _config = config;
     _options = options == null ?
         new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) :
         new Dictionary<string, string>(options, StringComparer.OrdinalIgnoreCase);
 }
Ejemplo n.º 5
0
 public PythonUwpInterpreterFactory(InterpreterConfiguration configuration, string description) 
     : base(
           InterpreterGuid,
           description,
           configuration,
           true) {
 }
Ejemplo n.º 6
0
        public PythonVersion(string version)
        {
            PythonVersion selected;

            if (version == "Anaconda27")
            {
                selected = PythonPaths.Anaconda27 ?? PythonPaths.Anaconda27_x64;
            }
            else if (version == "Anaconda36")
            {
                selected = PythonPaths.Anaconda36 ?? PythonPaths.Anaconda36_x64;
            }
            else
            {
                var v            = System.Version.Parse(version).ToLanguageVersion();
                var candididates = PythonPaths.Versions.Where(pv => pv.IsCPython && pv.Version == v).ToArray();
                if (candididates.Length > 1)
                {
                    selected = candididates.FirstOrDefault(c => c.Isx64) ?? candididates.First();
                }
                else
                {
                    selected = candididates.FirstOrDefault();
                }
            }
            selected.AssertInstalled();

            Configuration = selected.Configuration;
            IsCPython     = selected.IsCPython;
        }
Ejemplo n.º 7
0
        public MockPythonInterpreterFactory(InterpreterConfiguration config, bool withStatusUpdater = false) {
            _config = config;

            _isCurrent = false;
            IsCurrentReason = NoDatabaseReason;

            _useUpdater = withStatusUpdater;
        }
Ejemplo n.º 8
0
 public LaunchConfiguration Clone(InterpreterConfiguration newConfig = null) {
     return new LaunchConfiguration(newConfig ?? _config, _options) {
         PreferWindowedInterpreter = PreferWindowedInterpreter,
         InterpreterPath = InterpreterPath,
         InterpreterArguments = InterpreterArguments,
         ScriptName = ScriptName,
         ScriptArguments = ScriptArguments,
         WorkingDirectory = WorkingDirectory,
         Environment = Environment != null ? new Dictionary<string, string>(Environment) : null,
         SearchPaths = SearchPaths?.ToList()
     };
 }
Ejemplo n.º 9
0
        internal static IVsInteractiveWindow/*!*/ EnsureReplWindow(IServiceProvider serviceProvider, InterpreterConfiguration config, PythonProjectNode project) {
            var compModel = serviceProvider.GetComponentModel();
            var provider = compModel.GetService<InteractiveWindowProvider>();
            var vsProjectContext = compModel.GetService<VsProjectContextProvider>();

            string replId = config != null ?
                PythonReplEvaluatorProvider.GetEvaluatorId(config) :
                PythonReplEvaluatorProvider.GetEvaluatorId(project);
            var window = provider.OpenOrCreate(replId);
            project?.AddActionOnClose(window, InteractiveWindowProvider.Close);

            return window;
        }
Ejemplo n.º 10
0
 public InterpreterPlaceholder(string id, string description) {
     Configuration = new InterpreterConfiguration(
         PlaceholderId + ";" + id.ToString(),
         description,
         null,
         null,
         null,
         null,
         InterpreterArchitecture.Unknown,
         new Version(),
         InterpreterUIMode.Normal
     );
 }
Ejemplo n.º 11
0
 public InterpreterPlaceholder(Guid id, string description) {
     Id = id;
     Description = description;
     Configuration = new InterpreterConfiguration(
         null,
         null,
         null,
         null,
         null,
         ProcessorArchitecture.None,
         null,
         InterpreterUIMode.Normal
     );
 }
Ejemplo n.º 12
0
        public MockPythonInterpreterFactory(
            Guid id,
            string description,
            InterpreterConfiguration config,
            bool withStatusUpdater = false
        ) {
            _config = config;
            Id = id;
            Description = description;

            _isCurrent = false;
            IsCurrentReason = NoDatabaseReason;

            _useUpdater = withStatusUpdater;
        }
Ejemplo n.º 13
0
        public static bool ShouldElevate(IServiceProvider site, InterpreterConfiguration config, string operation) {
            var opts = site.GetPythonToolsService().GeneralOptions;
            if (opts.ElevatePip) {
                return true;
            }

            try {
                // Create a test file and delete it immediately to ensure we can do it.
                // If this fails, prompt the user to see whether they want to elevate.
                var testFile = PathUtils.GetAvailableFilename(config.PrefixPath, "access-test", ".txt");
                using (new FileStream(testFile, FileMode.CreateNew, FileAccess.Write, FileShare.Delete, 4096, FileOptions.DeleteOnClose)) { }
                return false;
            } catch (IOException) {
            } catch (UnauthorizedAccessException) {
            }

            var td = new TaskDialog(site) {
                Title = Strings.ProductTitle,
                MainInstruction = Strings.ElevateForInstallPackage_MainInstruction,
                AllowCancellation = true,
            };
            var elevate = new TaskDialogButton(Strings.ElevateForInstallPackage_Elevate, Strings.ElevateForInstallPackage_Elevate_Note) {
                ElevationRequired = true
            };
            var noElevate = new TaskDialogButton(Strings.ElevateForInstallPackage_DoNotElevate, Strings.ElevateForInstallPackage_DoNotElevate_Note);
            var elevateAlways = new TaskDialogButton(Strings.ElevateForInstallPackage_ElevateAlways, Strings.ElevateForInstallPackage_ElevateAlways_Note) {
                ElevationRequired = true
            };
            td.Buttons.Add(elevate);
            td.Buttons.Add(noElevate);
            td.Buttons.Add(elevateAlways);
            td.Buttons.Add(TaskDialogButton.Cancel);
            var sel = td.ShowModal();
            if (sel == TaskDialogButton.Cancel) {
                throw new OperationCanceledException();
            }

            if (sel == noElevate) {
                return false;
            }

            if (sel == elevateAlways) {
                opts.ElevatePip = true;
                opts.Save();
            }

            return true;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Creates a new interpreter factory with the specified options. This
        /// interpreter always includes a cached completion database.
        /// </summary>
        public static PythonInterpreterFactoryWithDatabase CreateInterpreterFactory(InterpreterConfiguration configuration, InterpreterFactoryCreationOptions options = null) {
            options = options?.Clone() ?? new InterpreterFactoryCreationOptions();

            if (string.IsNullOrEmpty(options.DatabasePath)) {
                options.DatabasePath = Path.Combine(
                    PythonTypeDatabase.CompletionDatabasePath,
                    GetRelativePathForConfigurationId(configuration.Id)
                );
            }

            var fact = new CPythonInterpreterFactory(configuration, options);
            if (options.WatchFileSystem) {
                fact.BeginRefreshIsCurrent();
            }
            return fact;
        }
Ejemplo n.º 15
0
        internal static IVsInteractiveWindow/*!*/ EnsureReplWindow(IServiceProvider serviceProvider, InterpreterConfiguration config, PythonProjectNode project) {
            var compModel = serviceProvider.GetComponentModel();
            var provider = compModel.GetService<InteractiveWindowProvider>();
            var vsProjectContext = compModel.GetService<VsProjectContextProvider>();

            var projectId = project != null ? PythonReplEvaluatorProvider.GetEvaluatorId(project) : null;
            var configId = config != null ? PythonReplEvaluatorProvider.GetEvaluatorId(config) : null;

            IVsInteractiveWindow window;

            // If we find an open window for the project, prefer that to a per-config one
            if (!string.IsNullOrEmpty(projectId)) {
                window = provider.Open(projectId);
                if (window != null) {
                    if (window.InteractiveWindow.GetPythonEvaluator()?.AssociatedProjectHasChanged == true) {
                        // We have an existing window, but it needs to be reset.
                        // Let's create a new one
                        window = provider.Create(projectId);
                        project.AddActionOnClose(window, InteractiveWindowProvider.Close);
                    }

                    return window;
                }
            }

            // If we find an open window for the configuration, return that
            if (!string.IsNullOrEmpty(configId)) {
                window = provider.Open(configId);
                if (window != null) {
                    return window;
                }
            }

            // No window found, so let's create one
            if (!string.IsNullOrEmpty(projectId)) {
                window = provider.Create(projectId);
                project.AddActionOnClose(window, InteractiveWindowProvider.Close);
            } else if (!string.IsNullOrEmpty(configId)) {
                window = provider.Create(configId);
            } else {
                var interpService = compModel.GetService<IInterpreterOptionsService>();
                window = provider.Create(PythonReplEvaluatorProvider.GetEvaluatorId(interpService.DefaultInterpreter.Configuration));
            }

            return window;
        }
Ejemplo n.º 16
0
        public DerivedInterpreterFactory(
            PythonInterpreterFactoryWithDatabase baseFactory,
            InterpreterConfiguration config,
            InterpreterFactoryCreationOptions options
            )
            : base(config, options.WatchLibraryForNewModules)
        {
            _base = baseFactory;
            _base.IsCurrentChanged += Base_IsCurrentChanged;
            _base.NewDatabaseAvailable += Base_NewDatabaseAvailable;

            if (Volatile.Read(ref _deferRefreshIsCurrent)) {
                // This rare race condition is due to a design flaw that is in
                // shipped public API and cannot be fixed without breaking
                // compatibility with 3rd parties.
                RefreshIsCurrent();
            }
        }
Ejemplo n.º 17
0
 public NotFoundInterpreterFactory(
     string id,
     Version version,
     string description = null,
     string prefixPath = null,
     InterpreterArchitecture architecture = default(InterpreterArchitecture),
     string descriptionSuffix = null) {
     Configuration = new InterpreterConfiguration(
         id,
         description ?? "Unknown Python {0}{1: ()} (unavailable)".FormatUI(version, architecture),
         prefixPath,
         null,
         null,
         null,
         architecture,
         version,
         InterpreterUIMode.CannotBeDefault | InterpreterUIMode.CannotBeConfigured
     );
 }
Ejemplo n.º 18
0
 public NotFoundInterpreterFactory(
     string id,
     Version version,
     string description = null,
     string prefixPath = null,
     ProcessorArchitecture architecture = ProcessorArchitecture.None,
     string descriptionSuffix = null)
 {
     Configuration = new InterpreterConfiguration(
         id,
         string.IsNullOrEmpty(description) ? "Unknown Python" : description,
         prefixPath,
         null,
         null,
         null,
         null,
         architecture,
         version,
         InterpreterUIMode.CannotBeDefault | InterpreterUIMode.CannotBeConfigured,
         "(unavailable)"
     );
 }
Ejemplo n.º 19
0
 public PythonUwpInterpreterFactory(InterpreterConfiguration configuration)
     : base(configuration,
           true)
 {
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Create a PythonInterpreterView with values from an IPythonInterpreterFactory.
 /// </summary>
 public PythonInterpreterView(InterpreterConfiguration config) {
     _name = config.Description;
     _id = config.Id;
     _path = config.InterpreterPath;
 }
Ejemplo n.º 21
0
 public InterpreterOptions(PythonToolsService pyService, InterpreterConfiguration config) {
     _pyService = pyService;
     _config = config;
 }
 public static bool IsAvailable(this InterpreterConfiguration configuration)
 {
     return(File.Exists(configuration.InterpreterPath) &&
            File.Exists(configuration.GetWindowsInterpreterPath()));
 }
Ejemplo n.º 23
0
        public string AddConfigurableInterpreter(string name, InterpreterConfiguration config)
        {
            using (_cpythonProvider.Value.SuppressDiscoverFactories()) {
                var collection = CustomInterpreterKey + "\\" + name;
                using (var key = Registry.CurrentUser.CreateSubKey(CustomInterpreterKey, true)) {
                    key.SetValue(DescriptionKey, Strings.CustomEnvironmentLabel);
                }

                using (var key = Registry.CurrentUser.CreateSubKey(collection, true)) {
                    if (config.Architecture != InterpreterArchitecture.Unknown)
                    {
                        key.SetValue(ArchitectureKey, config.Architecture.ToPEP514());
                    }
                    else
                    {
                        key.DeleteValue(ArchitectureKey, false);
                    }
                    if (config.Version != new Version())
                    {
                        key.SetValue(VersionKey, config.Version.ToString());
                    }
                    else
                    {
                        key.DeleteValue(VersionKey, false);
                    }
                    if (!string.IsNullOrEmpty(config.PathEnvironmentVariable))
                    {
                        key.SetValue(PathEnvVarKey, config.PathEnvironmentVariable);
                    }
                    else
                    {
                        key.DeleteValue(PathEnvVarKey, false);
                    }
                    if (!string.IsNullOrEmpty(config.Description))
                    {
                        key.SetValue(DescriptionKey, config.Description);
                    }
                    else
                    {
                        key.DeleteValue(DescriptionKey, false);
                    }

                    var vsConfig = (VisualStudioInterpreterConfiguration)config;
                    using (var installPath = key.CreateSubKey("InstallPath")) {
                        string exePath = config.InterpreterPath ?? vsConfig.WindowsInterpreterPath ?? "";
                        if (!string.IsNullOrEmpty(vsConfig.PrefixPath))
                        {
                            installPath.SetValue("", vsConfig.PrefixPath);
                        }
                        else if (!string.IsNullOrWhiteSpace(exePath))
                        {
                            installPath.SetValue("", Path.GetDirectoryName(exePath));
                        }
                        installPath.SetValue(WindowsPathKey, config.GetWindowsInterpreterPath() ?? string.Empty);
                        installPath.SetValue(PathKey, config.InterpreterPath ?? string.Empty);
                    }
                }
            }

            return(CPythonInterpreterFactoryConstants.GetInterpreterId(CustomCompany, name));
        }
 public NotFoundInterpreterFactory(
     Guid id,
     Version version,
     string description = null,
     string prefixPath = null
 ) {
     Id = id;
     Configuration = new InterpreterConfiguration(
         prefixPath,
         null,
         null,
         null,
         null,
         ProcessorArchitecture.None,
         version
     );
     Description = string.IsNullOrEmpty(description) ? string.Format("Unknown Python {0}", version) : description;
 }
Ejemplo n.º 25
0
        private static ProjectItemElement AddVirtualEnvironment(
            ProjectRootElement project,
            string sourcePath,
            InterpreterConfiguration config
        ) {
            var prefixPath = config.PrefixPath ?? string.Empty;
            var interpreterPath = string.IsNullOrEmpty(config.InterpreterPath) ?
                string.Empty :
                PathUtils.GetRelativeFilePath(prefixPath, config.InterpreterPath);
            var windowInterpreterPath = string.IsNullOrEmpty(config.WindowsInterpreterPath) ?
                string.Empty :
                PathUtils.GetRelativeFilePath(prefixPath, config.WindowsInterpreterPath);
            prefixPath = PathUtils.GetRelativeDirectoryPath(sourcePath, prefixPath);

            return project.AddItem(
                MSBuildConstants.InterpreterItem,
                prefixPath,
                new Dictionary<string, string> {
                    { MSBuildConstants.IdKey, Path.GetFileName(sourcePath) },
                    { MSBuildConstants.DescriptionKey, config.Description },
                    { MSBuildConstants.BaseInterpreterKey, config.Id },
                    { MSBuildConstants.InterpreterPathKey, interpreterPath },
                    { MSBuildConstants.WindowsPathKey, windowInterpreterPath },
                    { MSBuildConstants.VersionKey, config.Version.ToString() },
                    { MSBuildConstants.ArchitectureKey, config.Architecture.ToString("X") },
                    { MSBuildConstants.PathEnvVarKey, config.PathEnvironmentVariable }
                }
            );
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Returns <c>true</c> if the factory can be configured.
 /// </summary>
 /// <remarks>New in 2.2</remarks>
 public static bool CanBeConfigured(this InterpreterConfiguration config)
 {
     return(config != null &&
            !config.UIMode.HasFlag(InterpreterUIMode.CannotBeConfigured));
 }
 public static string GetWindowsInterpreterPath(this InterpreterConfiguration config)
 => config != null ? ((VisualStudioInterpreterConfiguration)config).WindowsInterpreterPath : null;
 public static string GetPrefixPath(this InterpreterConfiguration config)
 => config != null ? ((VisualStudioInterpreterConfiguration)config).PrefixPath : null;
 /// <summary>
 /// Returns <c>true</c> if the factory should appear in the UI.
 /// </summary>
 /// <remarks>New in 2.2</remarks>
 public static bool IsUIVisible(this InterpreterConfiguration config)
 {
     return(config is VisualStudioInterpreterConfiguration vsConfig &&
            !vsConfig.UIMode.HasFlag(InterpreterUIMode.Hidden));
 }
 public FactoryInfo(InterpreterConfiguration configuration)
 {
     Config = configuration;
 }
 /// <summary>
 /// Returns true if the configuration can be run. This checks whether
 /// the configured InterpreterPath value is an actual file.
 /// </summary>
 public static bool IsRunnable(this InterpreterConfiguration config)
 {
     return(config != null &&
            !InterpreterRegistryConstants.IsNoInterpretersFactory(config.Id) &&
            File.Exists(config.InterpreterPath));
 }
 internal AnalysisOnlyInterpreterFactory(Dictionary <string, object> properties)
     : this(InterpreterConfiguration.FromDictionary(properties))
 {
 }
Ejemplo n.º 33
0
        private PythonProjectNode GetAssociatedPythonProject(InterpreterConfiguration interpreter = null) {
            _serviceProvider.GetUIThread().MustBeCalledFromUIThread();

            var moniker = ProjectMoniker;
            if (interpreter == null) {
                interpreter = Configuration?.Interpreter;
            }

            if (string.IsNullOrEmpty(moniker) && interpreter != null) {
                var interpreterService = _serviceProvider.GetComponentModel().GetService<IInterpreterRegistryService>();
                moniker = interpreterService.GetProperty(interpreter.Id, "ProjectMoniker") as string;
            }

            if (string.IsNullOrEmpty(moniker)) {
                return null;
            }

            return _serviceProvider.GetProjectFromFile(moniker);
        }
Ejemplo n.º 34
0
        public string AddConfigurableInterpreter(string name, InterpreterConfiguration config) {
            var collection = PythonInterpreterKey + "\\" + name;
            using (var key = Registry.CurrentUser.CreateSubKey(collection, true)) {
                if (config.Architecture != InterpreterArchitecture.Unknown) {
                    key.SetValue(ArchitectureKey, config.Architecture.ToPEP514());
                } else {
                    key.DeleteValue(ArchitectureKey, false);
                }
                if (config.Version != new Version()) {
                    key.SetValue(VersionKey, config.Version.ToString());
                } else {
                    key.DeleteValue(VersionKey, false);
                }
                if (!string.IsNullOrEmpty(config.PathEnvironmentVariable)) {
                    key.SetValue(PathEnvVarKey, config.PathEnvironmentVariable);
                } else {
                    key.DeleteValue(PathEnvVarKey, false);
                }
                if (!string.IsNullOrEmpty(config.Description)) {
                    key.SetValue(DescriptionKey, config.Description);
                } else {
                    key.DeleteValue(DescriptionKey, false);
                }
                using (var installPath = key.CreateSubKey("InstallPath")) {
                    string exePath = config.InterpreterPath ?? config.WindowsInterpreterPath ?? "";
                    if (!string.IsNullOrEmpty(config.PrefixPath)) {
                        installPath.SetValue("", config.PrefixPath);
                    } else if (!string.IsNullOrWhiteSpace(exePath)) {
                        installPath.SetValue("", Path.GetDirectoryName(exePath));
                    }
                    installPath.SetValue(WindowsPathKey, config.WindowsInterpreterPath ?? string.Empty);
                    installPath.SetValue(PathKey, config.InterpreterPath ?? string.Empty);
                }
            }

            // ensure we're up to date...
            _cpythonProvider.Value.DiscoverInterpreterFactories();

            return CPythonInterpreterFactoryConstants.GetInterpreterId("VisualStudio", name);

        }
Ejemplo n.º 35
0
 public string AddConfigurableInterpreter(string name, InterpreterConfiguration config) {
     throw new NotImplementedException();
 }
 public AnalysisOnlyInterpreterFactory(InterpreterConfiguration config)
 {
     Configuration = config;
 }
Ejemplo n.º 37
0
 public PythonVersion(Microsoft.PythonTools.Interpreter.InterpreterConfiguration config, bool cPython = false)
 {
     Configuration = config;
     IsCPython     = cPython;
 }
 /// <summary>
 /// Returns <c>true</c> if the factory can be automatically selected as
 /// the default interpreter.
 /// </summary>
 /// <remarks>New in 2.2</remarks>
 public static bool CanBeAutoDefault(this InterpreterConfiguration config)
 {
     return(config is VisualStudioInterpreterConfiguration vsConfig &&
            !vsConfig.UIMode.HasFlag(InterpreterUIMode.CannotBeDefault) &&
            !vsConfig.UIMode.HasFlag(InterpreterUIMode.CannotBeAutoDefault));
 }
 public ConfiguredFactoryInfo(MSBuildProjectInterpreterFactoryProvider factoryProvider, InterpreterConfiguration config) : base(config)
 {
     _factoryProvider = factoryProvider;
 }
Ejemplo n.º 40
0
        internal static string GetScriptsPath(
            IServiceProvider provider,
            string displayName,
            InterpreterConfiguration config,
            bool onlyIfExists = true
        ) {
            // TODO: Allow customizing the scripts path
            //var root = _serviceProvider.GetPythonToolsService().InteractiveOptions.ScriptsPath;
            var root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            root = PathUtils.GetAbsoluteDirectoryPath(root, Path.Combine(
                "Visual Studio " + AssemblyVersionInfo.VSName,
                "Python Scripts"
            ));

            string candidate;
            if (!string.IsNullOrEmpty(displayName)) {
                candidate = PathUtils.GetAbsoluteDirectoryPath(root, displayName);
                if (!onlyIfExists || Directory.Exists(candidate)) {
                    return candidate;
                }
            }

            var version = config?.Version?.ToString();
            if (!string.IsNullOrEmpty(version)) {
                candidate = PathUtils.GetAbsoluteDirectoryPath(root, version);
                if (!onlyIfExists || Directory.Exists(candidate)) {
                    return candidate;
                }
            }

            return null;
        }
        /// <summary>
        /// Call to find interpreters in the associated project. Separated from
        /// the constructor to allow exceptions to be handled without causing
        /// the project node to be invalid.
        /// </summary>
        private bool DiscoverInterpreters(ProjectInfo projectInfo)
        {
            // <Interpreter Include="InterpreterDirectory">
            //   <Id>factoryProviderId;interpreterFactoryId</Id>
            //   <BaseInterpreter>factoryProviderId;interpreterFactoryId</BaseInterpreter>
            //   <Version>...</Version>
            //   <InterpreterPath>...</InterpreterPath>
            //   <WindowsInterpreterPath>...</WindowsInterpreterPath>
            //   <LibraryPath>...</LibraryPath>
            //   <PathEnvironmentVariable>...</PathEnvironmentVariable>
            //   <Description>...</Description>
            // </Interpreter>
            var projectHome = PathUtils.GetAbsoluteDirectoryPath(
                Path.GetDirectoryName(projectInfo.FullPath),
                projectInfo.GetPropertyValue("ProjectHome")
                );
            var factories = new Dictionary <string, FactoryInfo>();

            foreach (var item in projectInfo.GetInterpreters())
            {
                // Errors in these options are fatal, so we set anyError and
                // continue with the next entry.
                var dir = GetValue(item, "EvaluatedInclude");
                if (!PathUtils.IsValidPath(dir))
                {
                    Log("Interpreter has invalid path: {0}", dir ?? "(null)");
                    continue;
                }
                dir = PathUtils.GetAbsoluteDirectoryPath(projectHome, dir);

                var id = GetValue(item, MSBuildConstants.IdKey);
                if (string.IsNullOrEmpty(id))
                {
                    Log("Interpreter {0} has invalid value for '{1}': {2}", dir, MSBuildConstants.IdKey, id);
                    continue;
                }
                if (factories.ContainsKey(id))
                {
                    Log("Interpreter {0} has a non-unique id: {1}", dir, id);
                    continue;
                }

                var     verStr = GetValue(item, MSBuildConstants.VersionKey);
                Version ver;
                if (string.IsNullOrEmpty(verStr) || !Version.TryParse(verStr, out ver))
                {
                    Log("Interpreter {0} has invalid value for '{1}': {2}", dir, MSBuildConstants.VersionKey, verStr);
                    continue;
                }

                // The rest of the options are non-fatal. We create an instance
                // of NotFoundError with an amended description, which will
                // allow the user to remove the entry from the project file
                // later.
                bool hasError = false;

                bool hasDescription = true;
                var  description    = GetValue(item, MSBuildConstants.DescriptionKey);
                if (string.IsNullOrEmpty(description))
                {
                    hasDescription = false;
                    description    = PathUtils.CreateFriendlyDirectoryPath(projectHome, dir);
                }

                var baseInterpId = GetValue(item, MSBuildConstants.BaseInterpreterKey);

                var path = GetValue(item, MSBuildConstants.InterpreterPathKey);
                if (!PathUtils.IsValidPath(path))
                {
                    Log("Interpreter {0} has invalid value for '{1}': {2}", dir, MSBuildConstants.InterpreterPathKey, path);
                    hasError = true;
                }
                else if (!hasError)
                {
                    path = PathUtils.GetAbsoluteFilePath(dir, path);
                }

                var winPath = GetValue(item, MSBuildConstants.WindowsPathKey);
                if (!PathUtils.IsValidPath(winPath))
                {
                    Log("Interpreter {0} has invalid value for '{1}': {2}", dir, MSBuildConstants.WindowsPathKey, winPath);
                    hasError = true;
                }
                else if (!hasError)
                {
                    winPath = PathUtils.GetAbsoluteFilePath(dir, winPath);
                }

                var libPath = GetValue(item, MSBuildConstants.LibraryPathKey);
                if (string.IsNullOrEmpty(libPath))
                {
                    libPath = "lib";
                }
                if (!PathUtils.IsValidPath(libPath))
                {
                    Log("Interpreter {0} has invalid value for '{1}': {2}", dir, MSBuildConstants.LibraryPathKey, libPath);
                    hasError = true;
                }
                else if (!hasError)
                {
                    libPath = PathUtils.GetAbsoluteDirectoryPath(dir, libPath);
                }

                InterpreterConfiguration baseInterp = null;
                if (!string.IsNullOrEmpty(baseInterpId))
                {
                    // It's a valid GUID, so find a suitable base. If we
                    // don't find one now, we'll try and figure it out from
                    // the pyvenv.cfg/orig-prefix.txt files later.
                    // Using an empty GUID will always go straight to the
                    // later lookup.
                    baseInterp = FindConfiguration(baseInterpId);
                }

                var pathVar = GetValue(item, MSBuildConstants.PathEnvVarKey);
                if (string.IsNullOrEmpty(pathVar))
                {
                    if (baseInterp != null)
                    {
                        pathVar = baseInterp.PathEnvironmentVariable;
                    }
                    else
                    {
                        pathVar = "PYTHONPATH";
                    }
                }

                string arch = null;

                if (baseInterp == null)
                {
                    arch = GetValue(item, MSBuildConstants.ArchitectureKey);
                    if (string.IsNullOrEmpty(arch))
                    {
                        arch = "x86";
                    }
                }

                if (baseInterp == null && !hasError)
                {
                    // Only thing missing is the base interpreter, so let's try
                    // to find it using paths
                    baseInterp = FindBaseInterpreterFromVirtualEnv(dir, libPath);

                    if (baseInterp == null)
                    {
                        Log("Interpreter {0} has invalid value for '{1}': {2}", dir, MSBuildConstants.BaseInterpreterKey, baseInterpId ?? "(null)");
                        hasError = true;
                    }
                }

                string fullId = GetInterpreterId(projectInfo.FullPath, id);

                FactoryInfo info;
                if (hasError)
                {
                    info = new ErrorFactoryInfo(fullId, ver, description, dir);
                }
                else
                {
                    Debug.Assert(baseInterp != null, "we reported an error if we didn't have a base interpreter");

                    if (!hasDescription)
                    {
                        description = string.Format("{0} ({1})", description, baseInterp.Description);
                    }

                    info = new ConfiguredFactoryInfo(
                        this,
                        baseInterp,
                        new InterpreterConfiguration(
                            fullId,
                            description,
                            dir,
                            path,
                            winPath,
                            libPath,
                            pathVar,
                            baseInterp.Architecture,
                            baseInterp.Version,
                            InterpreterUIMode.CannotBeDefault | InterpreterUIMode.CannotBeConfigured | InterpreterUIMode.SupportsDatabase
                            )
                        );
                }

                MergeFactory(projectInfo, factories, info);
            }

            HashSet <FactoryInfo> previousFactories = new HashSet <FactoryInfo>();

            if (projectInfo.Factories != null)
            {
                previousFactories.UnionWith(projectInfo.Factories.Values);
            }
            HashSet <FactoryInfo> newFactories = new HashSet <FactoryInfo>(factories.Values);

            bool anyChange = !newFactories.SetEquals(previousFactories);

            if (anyChange || projectInfo.Factories == null)
            {
                // Lock here mainly to ensure that any searches complete before
                // we trigger the changed event.
                lock (projectInfo) {
                    projectInfo.Factories = factories;
                }

                foreach (var removed in previousFactories.Except(newFactories))
                {
                    projectInfo.ContextProvider.InterpreterUnloaded(
                        projectInfo.Context,
                        removed.Config
                        );

                    IDisposable disp = removed as IDisposable;
                    if (disp != null)
                    {
                        disp.Dispose();
                    }
                }

                foreach (var added in newFactories.Except(previousFactories))
                {
                    foreach (var factory in factories)
                    {
                        projectInfo.ContextProvider.InterpreterLoaded(
                            projectInfo.Context,
                            factory.Value.Config
                            );
                    }
                }
            }

            return(anyChange);
        }
Ejemplo n.º 42
0
 public void InterpreterUnloaded(object context, InterpreterConfiguration factory) {
 }
Ejemplo n.º 43
0
 public UnavailableFactory(string id, string version) {
     Id = Guid.Parse(id);
     Configuration = new InterpreterConfiguration(Version.Parse(version));
 }
Ejemplo n.º 44
0
 private EnvironmentView(string id) {
     Configuration = new InterpreterConfiguration(id, id);
 }
Ejemplo n.º 45
0
        /// <summary>
        /// Creates a new interpreter factory backed by a type database.
        /// </summary>
        /// <remarks>
        /// <see cref="RefreshIsCurrent"/> must be called after creation to
        /// ensure the database state is correctly reflected.
        /// </remarks>
        public PythonInterpreterFactoryWithDatabase(
            InterpreterConfiguration config,
            InterpreterFactoryCreationOptions options
            )
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }
            if (options == null)
            {
                options = new InterpreterFactoryCreationOptions();
            }
            Configuration = config;

            _databasePath = options.DatabasePath;

            // Avoid creating a interpreter with an unsupported version.
            // https://github.com/Microsoft/PTVS/issues/706
            try {
                var langVer = config.Version.ToLanguageVersion();
            } catch (InvalidOperationException ex) {
                throw new ArgumentException(ex.Message, ex);
            }

            if (options.WatchFileSystem && !string.IsNullOrEmpty(DatabasePath))
            {
                // Assume the database is valid if the version is up to date, then
                // switch to invalid after we've checked.
                _isValid            = PythonTypeDatabase.IsDatabaseVersionCurrent(DatabasePath);
                _isCheckingDatabase = true;

                _verWatcher    = CreateDatabaseVerWatcher();
                _verDirWatcher = CreateDatabaseDirectoryWatcher();
#if DEBUG
                var creationStack = new StackTrace(true).ToString();
                Task.Delay(1000).ContinueWith(t => {
                    Debug.Assert(
                        _hasEverCheckedDatabase,
                        "Database check was not triggered for {0}".FormatUI(Configuration.Id),
                        creationStack
                        );
                });
#endif
            }
            else
            {
                // Assume the database is valid
                _isValid = true;
            }

            try {
                var pm = options.PackageManager;
                if (pm != null)
                {
                    pm.SetInterpreterFactory(this);
                    pm.InstalledFilesChanged += PackageManager_InstalledFilesChanged;
                    PackageManager            = pm;
                }
            } catch (NotSupportedException) {
            }
        }
Ejemplo n.º 46
0
 /// <summary>
 /// Returns <c>true</c> if the factory should appear in the UI.
 /// </summary>
 /// <remarks>New in 2.2</remarks>
 public static bool IsUIVisible(this InterpreterConfiguration config)
 {
     return(config != null &&
            !config.UIMode.HasFlag(InterpreterUIMode.Hidden));
 }
Ejemplo n.º 47
0
 /// <summary>
 /// Returns <c>true</c> if the factory can be automatically selected as
 /// the default interpreter.
 /// </summary>
 /// <remarks>New in 2.2</remarks>
 public static bool CanBeAutoDefault(this InterpreterConfiguration config)
 {
     return(config != null &&
            !config.UIMode.HasFlag(InterpreterUIMode.CannotBeDefault) &&
            !config.UIMode.HasFlag(InterpreterUIMode.CannotBeAutoDefault));
 }
Ejemplo n.º 48
0
        internal EnvironmentView(
            IInterpreterOptionsService service,
            IInterpreterRegistryService registry,
            IPythonInterpreterFactory factory,
            Redirector redirector
        ) {
            if (service == null) {
                throw new ArgumentNullException(nameof(service));
            }
            if (registry == null) {
                throw new ArgumentNullException(nameof(registry));
            }
            if (factory == null) {
                throw new ArgumentNullException(nameof(factory));
            }
            if (factory.Configuration == null) {
                throw new ArgumentException("factory must include a configuration");
            }

            _service = service;
            _registry = registry;
            Factory = factory;
            Configuration = Factory.Configuration;

            _withDb = factory as IPythonInterpreterFactoryWithDatabase;
            if (_withDb != null) {
                _withDb.IsCurrentChanged += Factory_IsCurrentChanged;
                IsCheckingDatabase = _withDb.IsCheckingDatabase;
                IsCurrent = _withDb.IsCurrent;
            }
            

            if (_service.IsConfigurable(Factory.Configuration.Id)) {
                IsConfigurable = true;
            }

            Description = Factory.Configuration.Description;
            IsDefault = (_service != null && _service.DefaultInterpreterId == Configuration.Id);

            PrefixPath = Factory.Configuration.PrefixPath;
            InterpreterPath = Factory.Configuration.InterpreterPath;
            WindowsInterpreterPath = Factory.Configuration.WindowsInterpreterPath;

            Extensions = new ObservableCollection<object>();
            Extensions.Add(new EnvironmentPathsExtensionProvider());
            if (IsConfigurable) {
                Extensions.Add(new ConfigurationExtensionProvider(_service, alwaysCreateNew: false));
            }

            CanBeDefault = Factory.CanBeDefault();

            Company = _registry.GetProperty(Factory.Configuration.Id, CompanyKey) as string ?? "";
            SupportUrl = _registry.GetProperty(Factory.Configuration.Id, SupportUrlKey) as string ?? "";
        }
Ejemplo n.º 49
0
        public void Search(RegistryKey root, InterpreterArchitecture assumedArch)
        {
            if (root == null)
            {
                return;
            }

            var companies = GetSubkeys(root);

            foreach (var company in companies)
            {
                if ("PyLauncher".Equals(company, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                bool pythonCore = PythonCoreCompany.Equals(company, StringComparison.OrdinalIgnoreCase);

                using (var companyKey = root.OpenSubKey(company)) {
                    if (companyKey == null)
                    {
                        continue;
                    }

                    var companyDisplay    = companyKey.GetValue("DisplayName") as string;
                    var companySupportUrl = companyKey.GetValue("SupportUrl") as string;

                    if (pythonCore)
                    {
                        companyDisplay    = companyDisplay ?? PythonCoreCompanyDisplayName;
                        companySupportUrl = companySupportUrl ?? PythonCoreSupportUrl;
                    }
                    else
                    {
                        companyDisplay = companyDisplay ?? company;
                    }

                    var tags = GetSubkeys(companyKey);
                    foreach (var tag in tags)
                    {
                        using (var tagKey = companyKey.OpenSubKey(tag))
                            using (var installKey = tagKey?.OpenSubKey("InstallPath")) {
                                var config = TryReadConfiguration(company, tag, tagKey, installKey, pythonCore, assumedArch);
                                if (config == null)
                                {
                                    continue;
                                }

                                if (_seenIds.Add(config.Id))
                                {
                                    var supportUrl = tagKey.GetValue("SupportUrl") as string ?? companySupportUrl;

                                    // We don't want to send people to http://python.org, even
                                    // if that's what is in the registry, so catch and fix it.
                                    if (!string.IsNullOrEmpty(supportUrl))
                                    {
                                        var url = supportUrl.TrimEnd('/');
                                        if (url.Equals("http://www.python.org", StringComparison.OrdinalIgnoreCase) ||
                                            url.Equals("http://python.org", StringComparison.OrdinalIgnoreCase))
                                        {
                                            supportUrl = PythonCoreSupportUrl;
                                        }
                                    }

                                    var info = new PythonInterpreterInformation(config, companyDisplay, companySupportUrl, supportUrl);
                                    _info.Add(info);
                                }
                            }
                    }
                }
            }

            InterpreterConfiguration.DisambiguateDescriptions(_info.Select(i => i.Configuration).ToArray());
        }