protected override void CreateFactory() { var dbPath = PathUtils.GetAbsoluteDirectoryPath( Config.PrefixPath, ".ptvs" ); _factory = InterpreterFactoryCreator.CreateInterpreterFactory( Config, new InterpreterFactoryCreationOptions { PackageManager = new PipPackageManager(), DatabasePath = dbPath, WatchFileSystem = true, NoDatabase = PythonInterpreterInformation._experimentalFactory.Value } ); }
public IPythonInterpreterFactory EnsureFactory() { if (Factory == null) { lock (this) { if (Factory == null) { Factory = InterpreterFactoryCreator.CreateInterpreterFactory( Configuration, new InterpreterFactoryCreationOptions() { WatchLibraryForNewModules = true } ); } } } return(Factory); }
protected override void CreateFactory() { var dbPath = PathUtils.GetAbsoluteDirectoryPath( Config.PrefixPath, ".ptvs" ); _factory = InterpreterFactoryCreator.CreateInterpreterFactory( Config, new InterpreterFactoryCreationOptions { PackageManager = new PipPackageManager(), WatchFileSystem = true, NoDatabase = ExperimentalOptions.NoDatabaseFactory, DatabasePath = ExperimentalOptions.NoDatabaseFactory ? DatabasePathSelector.CalculateProjectLocalDatabasePath(_factoryProvider._site, Config, 1) : DatabasePathSelector.CalculateProjectLocalDatabasePath(_factoryProvider._site, Config, 0) } ); }
public IPythonInterpreterFactory EnsureFactory() { if (Factory == null) { lock (this) { if (Factory == null) { Factory = InterpreterFactoryCreator.CreateInterpreterFactory( Configuration, new InterpreterFactoryCreationOptions { PackageManager = new PipPackageManager(), WatchFileSystem = true, NoDatabase = _experimentalFactory.Value } ); } } } return(Factory); }
private PythonInterpreterFactoryWithDatabase LoadUserDefinedInterpreter(SettingsStore store, string guid) { // PythonInterpreters\ // Id\ // Description // InterpreterPath // WindowsInterpreterPath // Architecture // Version // PathEnvironmentVariable Guid id; string collection; if (Guid.TryParse(guid, out id) && store.CollectionExists((collection = PythonInterpreterKey + "\\" + id.ToString("B")))) { var path = store.GetString(collection, PathKey, string.Empty); var winPath = store.GetString(collection, WindowsPathKey, string.Empty); var libPath = store.GetString(collection, LibraryPathKey, string.Empty); var arch = store.GetString(collection, ArchitectureKey, string.Empty); var version = store.GetString(collection, VersionKey, string.Empty); var pathEnvVar = store.GetString(collection, PathEnvVarKey, string.Empty); var description = store.GetString(collection, DescriptionKey, string.Empty); return(InterpreterFactoryCreator.CreateInterpreterFactory( new InterpreterFactoryCreationOptions { LanguageVersionString = version, Id = id, Description = description, InterpreterPath = path, WindowInterpreterPath = winPath, LibraryPath = libPath, PathEnvironmentVariableName = pathEnvVar, ArchitectureString = arch, WatchLibraryForNewModules = true } )); } return(null); }
protected override void CreateFactory() { if (!ExperimentalOptions.NoDatabaseFactory) { _factory = new LegacyDB.CPythonInterpreterFactory( Config, new InterpreterFactoryCreationOptions { WatchFileSystem = true, DatabasePath = DatabasePathSelector.CalculateProjectLocalDatabasePath(_factoryProvider._site, Config, 0) } ); } else { _factory = InterpreterFactoryCreator.CreateInterpreterFactory( Config, new InterpreterFactoryCreationOptions { WatchFileSystem = true, DatabasePath = DatabasePathSelector.CalculateProjectLocalDatabasePath(_factoryProvider._site, Config, 1) } ); } }
private IPythonInterpreterFactory CreateFactory(PythonInterpreterInformation info) { if (!ExperimentalOptions.NoDatabaseFactory) { // Use the database-backed factory var fact = new LegacyDB.CPythonInterpreterFactory( info.Configuration, new InterpreterFactoryCreationOptions { WatchFileSystem = true, DatabasePath = DatabasePathSelector.CalculateGlobalDatabasePath(info.Configuration, LegacyDB.PythonTypeDatabase.FormatVersion) } ); fact.BeginRefreshIsCurrent(); return(fact); } return(InterpreterFactoryCreator.CreateInterpreterFactory( info.Configuration, new InterpreterFactoryCreationOptions { WatchFileSystem = true, DatabasePath = DatabasePathSelector.CalculateVSLocalDatabasePath(_site, info.Configuration, 1) } )); }
private bool RegisterInterpreters(HashSet <string> registeredPaths, RegistryKey python, ProcessorArchitecture?arch) { bool anyAdded = false; string[] subKeyNames = null; for (int retries = 5; subKeyNames == null && retries > 0; --retries) { try { subKeyNames = python.GetSubKeyNames(); } catch (IOException) { // Registry changed while enumerating subkeys. Give it a // short period to settle down and try again. // We are almost certainly being called from a background // thread, so sleeping here is fine. Thread.Sleep(100); } } if (subKeyNames == null) { return(false); } foreach (var key in subKeyNames) { Version version; ProcessorArchitecture?arch2; if (TryParsePythonVersion(key, out version, out arch2)) { if (version.Major == 2 && version.Minor <= 4) { // 2.4 and below not supported. continue; } var installPath = python.OpenSubKey(key + "\\InstallPath"); if (installPath != null) { var basePathObj = installPath.GetValue(""); if (basePathObj == null) { // http://pytools.codeplex.com/discussions/301384 // messed up install, we don't know where it lives, we can't use it. continue; } string basePath = basePathObj.ToString(); if (!PathUtils.IsValidPath(basePath)) { // Invalid path in registry continue; } if (!registeredPaths.Add(basePath)) { // registered in both HCKU and HKLM continue; } var actualArch = arch ?? arch2; if (!actualArch.HasValue) { actualArch = NativeMethods.GetBinaryType(Path.Combine(basePath, CPythonInterpreterFactoryConstants.ConsoleExecutable)); } var id = CPythonInterpreterFactoryConstants.Guid32; var description = CPythonInterpreterFactoryConstants.Description32; if (actualArch == ProcessorArchitecture.Amd64) { id = CPythonInterpreterFactoryConstants.Guid64; description = CPythonInterpreterFactoryConstants.Description64; } if (!_interpreters.Any(f => f.Id == id && f.Configuration.Version == version)) { IPythonInterpreterFactory fact; try { fact = InterpreterFactoryCreator.CreateInterpreterFactory( new InterpreterFactoryCreationOptions { LanguageVersion = version, Id = id, Description = string.Format("{0} {1}", description, version), InterpreterPath = Path.Combine(basePath, CPythonInterpreterFactoryConstants.ConsoleExecutable), WindowInterpreterPath = Path.Combine(basePath, CPythonInterpreterFactoryConstants.WindowsExecutable), LibraryPath = Path.Combine(basePath, CPythonInterpreterFactoryConstants.LibrarySubPath), PathEnvironmentVariableName = CPythonInterpreterFactoryConstants.PathEnvironmentVariableName, Architecture = actualArch ?? ProcessorArchitecture.None, WatchLibraryForNewModules = true } ); } catch (ArgumentException) { continue; } _interpreters.Add(fact); anyAdded = true; } } } } return(anyAdded); }
private bool RegisterInterpreters(HashSet <string> registeredPaths, RegistryKey python, ProcessorArchitecture?arch) { bool anyAdded = false; foreach (var key in python.GetSubKeyNames()) { Version version; ProcessorArchitecture?arch2; if (TryParsePythonVersion(key, out version, out arch2)) { if (version.Major == 2 && version.Minor <= 4) { // 2.4 and below not supported. continue; } var installPath = python.OpenSubKey(key + "\\InstallPath"); if (installPath != null) { var basePathObj = installPath.GetValue(""); if (basePathObj == null) { // http://pytools.codeplex.com/discussions/301384 // messed up install, we don't know where it lives, we can't use it. continue; } string basePath = basePathObj.ToString(); if (!CommonUtils.IsValidPath(basePath)) { // Invalid path in registry continue; } if (!registeredPaths.Add(basePath)) { // registered in both HCKU and HKLM continue; } var actualArch = arch ?? arch2; if (!actualArch.HasValue) { actualArch = NativeMethods.GetBinaryType(Path.Combine(basePath, CPythonInterpreterFactoryConstants.ConsoleExecutable)); } var id = CPythonInterpreterFactoryConstants.Guid32; var description = CPythonInterpreterFactoryConstants.Description32; if (actualArch == ProcessorArchitecture.Amd64) { id = CPythonInterpreterFactoryConstants.Guid64; description = CPythonInterpreterFactoryConstants.Description64; } if (!_interpreters.Any(f => f.Id == id && f.Configuration.Version == version)) { _interpreters.Add(InterpreterFactoryCreator.CreateInterpreterFactory( new InterpreterFactoryCreationOptions { LanguageVersion = version, Id = id, Description = string.Format("{0} {1}", description, version), InterpreterPath = Path.Combine(basePath, CPythonInterpreterFactoryConstants.ConsoleExecutable), WindowInterpreterPath = Path.Combine(basePath, CPythonInterpreterFactoryConstants.WindowsExecutable), LibraryPath = Path.Combine(basePath, CPythonInterpreterFactoryConstants.LibrarySubPath), PathEnvironmentVariableName = CPythonInterpreterFactoryConstants.PathEnvironmentVariableName, Architecture = actualArch ?? ProcessorArchitecture.None, WatchLibraryForNewModules = true } )); anyAdded = true; } } } } return(anyAdded); }
/// <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> /// <exception cref="InvalidDataException"> /// One or more interpreters failed to load. The error message should be /// presented to the user, but can otherwise be ignored. /// </exception> public void DiscoverInterpreters() { // <Interpreter Include="InterpreterDirectory"> // <Id>guid</Id> // <BaseInterpreter>guid</BaseInterpreter> // <Version>...</Version> // <InterpreterPath>...</InterpreterPath> // <WindowsInterpreterPath>...</WindowsInterpreterPath> // <LibraryPath>...</LibraryPath> // <PathEnvironmentVariable>...</PathEnvironmentVariable> // <Description>...</Description> // </Interpreter> var errors = new StringBuilder(); errors.AppendLine("Some project interpreters failed to load:"); bool anyChange = false, anyError = false; var projectHome = CommonUtils.GetAbsoluteDirectoryPath(_project.DirectoryPath, _project.GetPropertyValue("ProjectHome")); var factories = new Dictionary <IPythonInterpreterFactory, FactoryInfo>(); foreach (var item in _project.GetItems(InterpreterItem)) { IPythonInterpreterFactory fact; Guid id, baseId; // Errors in these options are fatal, so we set anyError and // continue with the next entry. var dir = item.EvaluatedInclude; if (!CommonUtils.IsValidPath(dir)) { errors.AppendLine(string.Format("Interpreter has invalid path: {0}", dir ?? "(null)")); anyError = true; continue; } dir = CommonUtils.GetAbsoluteDirectoryPath(projectHome, dir); var value = item.GetMetadataValue(IdKey); if (string.IsNullOrEmpty(value) || !Guid.TryParse(value, out id)) { errors.AppendLine(string.Format("Interpreter {0} has invalid value for '{1}': {2}", dir, IdKey, value)); anyError = true; continue; } if (factories.Keys.Any(f => f.Id == id)) { errors.AppendLine(string.Format("Interpreter {0} has a non-unique id: {1}", dir, id)); continue; } var verStr = item.GetMetadataValue(VersionKey); Version ver; if (string.IsNullOrEmpty(verStr) || !Version.TryParse(verStr, out ver)) { errors.AppendLine(string.Format("Interpreter {0} has invalid value for '{1}': {2}", dir, VersionKey, verStr)); anyError = true; 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; var description = item.GetMetadataValue(DescriptionKey); if (string.IsNullOrEmpty(description)) { description = CommonUtils.CreateFriendlyDirectoryPath(projectHome, dir); } value = item.GetMetadataValue(BaseInterpreterKey); PythonInterpreterFactoryWithDatabase baseInterp = null; if (!string.IsNullOrEmpty(value) && Guid.TryParse(value, out baseId)) { // 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. if (baseId != Guid.Empty) { baseInterp = _service.FindInterpreter(baseId, ver) as PythonInterpreterFactoryWithDatabase; } } var path = item.GetMetadataValue(InterpreterPathKey); if (!CommonUtils.IsValidPath(path)) { errors.AppendLine(string.Format("Interpreter {0} has invalid value for '{1}': {2}", dir, InterpreterPathKey, path)); hasError = true; } else if (!hasError) { path = CommonUtils.GetAbsoluteFilePath(dir, path); } var winPath = item.GetMetadataValue(WindowsPathKey); if (!CommonUtils.IsValidPath(winPath)) { errors.AppendLine(string.Format("Interpreter {0} has invalid value for '{1}': {2}", dir, WindowsPathKey, winPath)); hasError = true; } else if (!hasError) { winPath = CommonUtils.GetAbsoluteFilePath(dir, winPath); } var libPath = item.GetMetadataValue(LibraryPathKey); if (string.IsNullOrEmpty(libPath)) { libPath = "lib"; } if (!CommonUtils.IsValidPath(libPath)) { errors.AppendLine(string.Format("Interpreter {0} has invalid value for '{1}': {2}", dir, LibraryPathKey, libPath)); hasError = true; } else if (!hasError) { libPath = CommonUtils.GetAbsoluteDirectoryPath(dir, libPath); } var pathVar = item.GetMetadataValue(PathEnvVarKey); if (string.IsNullOrEmpty(pathVar)) { if (baseInterp != null) { pathVar = baseInterp.Configuration.PathEnvironmentVariable; } else { pathVar = "PYTHONPATH"; } } string arch = null; if (baseInterp == null) { arch = item.GetMetadataValue(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 = DerivedInterpreterFactory.FindBaseInterpreterFromVirtualEnv(dir, libPath, _service) as PythonInterpreterFactoryWithDatabase; if (baseInterp == null) { errors.AppendLine(string.Format("Interpreter {0} has invalid value for '{1}': {2}", dir, BaseInterpreterKey, value ?? "(null)")); hasError = true; } } if (hasError) { fact = new NotFoundInterpreterFactory( id, ver, string.Format("{0} (unavailable)", description), Directory.Exists(dir) ? dir : null ); } else if (baseInterp != null) { MigrateOldDerivedInterpreterFactoryDatabase(id, baseInterp.Configuration.Version, dir); fact = new DerivedInterpreterFactory( baseInterp, new InterpreterFactoryCreationOptions { LanguageVersion = baseInterp.Configuration.Version, Id = id, Description = description, InterpreterPath = path, WindowInterpreterPath = winPath, LibraryPath = libPath, PrefixPath = dir, PathEnvironmentVariableName = pathVar, Architecture = baseInterp.Configuration.Architecture, WatchLibraryForNewModules = true } ); } else { fact = InterpreterFactoryCreator.CreateInterpreterFactory(new InterpreterFactoryCreationOptions { LanguageVersion = ver, Id = id, Description = description, InterpreterPath = path, WindowInterpreterPath = winPath, LibraryPath = libPath, PrefixPath = dir, PathEnvironmentVariableName = pathVar, ArchitectureString = arch, WatchLibraryForNewModules = true }); } var existing = FindInterpreter(id, ver); if (existing != null && existing.IsEqual(fact)) { factories[existing] = new FactoryInfo(item, factories[existing].Owned); var disposable = fact as IDisposable; if (disposable != null) { disposable.Dispose(); } } else { _rootPaths[id] = dir; factories[fact] = new FactoryInfo(item, true); anyChange = true; } } // <InterpreterReference Include="{guid};{version}" /> foreach (var item in _project.GetItems(InterpreterReferenceItem)) { var match = InterpreterReferencePath.Match(item.EvaluatedInclude); if (match == null || !match.Success || !match.Groups.Cast <Group>().All(g => g.Success)) { errors.AppendLine(string.Format("Interpreter reference has invalid path: {0}", item.EvaluatedInclude)); anyError = true; continue; } Guid id; var value = match.Groups["id"]; if (string.IsNullOrEmpty(value.Value) || !Guid.TryParse(value.Value, out id)) { errors.AppendLine(string.Format("Interpreter reference has invalid id: {0}", value.Value ?? "(null)")); anyError = true; continue; } Version ver; value = match.Groups["version"]; if (string.IsNullOrEmpty(value.Value) || !Version.TryParse(value.Value, out ver)) { errors.AppendLine(string.Format("Interpreter reference has invalid version: {0}", value.Value ?? "(null)")); anyError = true; continue; } bool owned = false; var fact = _service.FindInterpreter(id, ver); if (fact == null) { owned = true; fact = new NotFoundInterpreterFactory(id, ver); } var existing = FindInterpreter(id, ver); if (existing != null) { factories[existing] = new FactoryInfo(item, factories[existing].Owned); if (owned) { ((PythonInterpreterFactoryWithDatabase)fact).Dispose(); } } else { factories[fact] = new FactoryInfo(item, owned); anyChange = true; } } if (anyChange || _factories == null || factories.Count != _factories.Count) { // Lock here mainly to ensure that any searches complete before // we trigger the changed event. lock (_factoriesLock) { _factories = factories; } OnInterpreterFactoriesChanged(); UpdateActiveInterpreter(); } if (anyError) { throw new InvalidDataException(errors.ToString()); } }
/// <summary> /// Creates a derived interpreter factory from the specified set of /// options. This function will modify the project, raise the /// <see cref="InterpreterFactoriesChanged"/> event and potentially /// display UI. /// </summary> /// <param name="options"> /// <para>The options for the new interpreter:</para> /// <para>Guid: ID of the base interpreter.</para> /// <para>Version: Version of the base interpreter. This will also be /// the version of the new interpreter.</para> /// <para>PythonPath: Either the path to the root of the virtual /// environment, or directly to the interpreter executable. If no file /// exists at the provided path, the name of the interpreter specified /// for the base interpreter is tried. If that is not found, "scripts" /// is added as the last directory. If that is not found, an exception /// is raised.</para> /// <para>PythonWindowsPath [optional]: The path to the interpreter /// executable for windowed applications. If omitted, an executable with /// the same name as the base interpreter's will be used if it exists. /// Otherwise, this will be set to the same as PythonPath.</para> /// <para>PathEnvVar [optional]: The name of the environment variable to /// set for search paths. If omitted, the value from the base /// interpreter will be used.</para> /// <para>Description [optional]: The user-friendly name of the /// interpreter. If omitted, the relative path from the project home to /// the directory containing the interpreter is used. If this path ends /// in "\\Scripts", the last segment is also removed.</para> /// </param> /// <returns>The ID of the created interpreter.</returns> public Guid CreateInterpreterFactory(InterpreterFactoryCreationOptions options) { var projectHome = CommonUtils.GetAbsoluteDirectoryPath(_project.DirectoryPath, _project.GetPropertyValue("ProjectHome")); var rootPath = CommonUtils.GetAbsoluteDirectoryPath(projectHome, options.PrefixPath); IPythonInterpreterFactory fact; var id = Guid.NewGuid(); var baseInterp = _service.FindInterpreter(options.Id, options.LanguageVersion) as PythonInterpreterFactoryWithDatabase; if (baseInterp != null) { var pathVar = options.PathEnvironmentVariableName; if (string.IsNullOrEmpty(pathVar)) { pathVar = baseInterp.Configuration.PathEnvironmentVariable; } var description = options.Description; if (string.IsNullOrEmpty(description)) { description = CommonUtils.CreateFriendlyDirectoryPath(projectHome, rootPath); int i = description.LastIndexOf("\\scripts", StringComparison.OrdinalIgnoreCase); if (i > 0) { description = description.Remove(i); } } MigrateOldDerivedInterpreterFactoryDatabase(id, baseInterp.Configuration.Version, options.PrefixPath); fact = new DerivedInterpreterFactory( baseInterp, new InterpreterFactoryCreationOptions { Id = id, LanguageVersion = baseInterp.Configuration.Version, Description = description, InterpreterPath = options.InterpreterPath, WindowInterpreterPath = options.WindowInterpreterPath, LibraryPath = options.LibraryPath, PrefixPath = options.PrefixPath, PathEnvironmentVariableName = pathVar, Architecture = baseInterp.Configuration.Architecture, WatchLibraryForNewModules = true } ); } else { fact = InterpreterFactoryCreator.CreateInterpreterFactory( new InterpreterFactoryCreationOptions { Id = id, LanguageVersion = options.LanguageVersion, Description = options.Description, InterpreterPath = options.InterpreterPath, WindowInterpreterPath = options.WindowInterpreterPath, LibraryPath = options.LibraryPath, PrefixPath = options.PrefixPath, PathEnvironmentVariableName = options.PathEnvironmentVariableName, Architecture = options.Architecture, WatchLibraryForNewModules = options.WatchLibraryForNewModules } ); } AddInterpreter(fact, true); return(id); }