public PythonTypeDatabase(
            PythonInterpreterFactoryWithDatabase factory,
            IEnumerable<string> databaseDirectories = null,
            PythonTypeDatabase innerDatabase = null
        ) {
            if (innerDatabase != null && factory.Configuration.Version != innerDatabase.LanguageVersion) {
                throw new InvalidOperationException("Language versions do not match");
            }

            _factory = factory;
            if (innerDatabase != null) {
                _sharedState = new SharedDatabaseState(innerDatabase._sharedState);
            } else {
                _sharedState = new SharedDatabaseState(_factory.Configuration.Version);
            }

            if (databaseDirectories != null) {
                foreach (var d in databaseDirectories) {
                    LoadDatabase(d);
                }
            }

            _sharedState.ListenForCorruptDatabase(this);
        }
 public PythonTypeDatabase CloneWithNewBuiltins(IBuiltinPythonModule newBuiltins) {
     var newDb = new PythonTypeDatabase(_factory, null, this);
     newDb._sharedState.BuiltinModule = newBuiltins;
     return newDb;
 }
 public ExtensionModuleLoader(PythonTypeDatabase typeDb, IPythonInterpreterFactory factory, string moduleName, string extensionFilename, CancellationToken cancel) {
     _typeDb = typeDb;
     _factory = factory;
     _moduleName = moduleName;
     _extensionFilename = extensionFilename;
     _cancel = cancel;
 }
Exemple #4
0
        /// <summary>
        /// Called to manually trigger a refresh of <see cref="IsCurrent"/>.
        /// After completion, <see cref="IsCurrentChanged"/> will always be
        /// raised, regardless of whether the values were changed.
        /// </summary>
        public virtual void RefreshIsCurrent()
        {
            lock (_isCurrentLock) {
                try {
                    _isCheckingDatabase = true;
                    OnIsCurrentChanged();

                    _generating     = PythonTypeDatabase.IsDatabaseRegenerating(DatabasePath);
                    WatchingLibrary = !_generating;

                    if (_generating)
                    {
                        // Skip the rest of the checks, because we know we're
                        // not current.
                    }
                    else if (!PythonTypeDatabase.IsDatabaseVersionCurrent(DatabasePath))
                    {
                        _isValid            = false;
                        _missingModules     = null;
                        _isCurrentException = null;
                    }
                    else
                    {
                        _isValid = true;
                        HashSet <string> existingDatabase = null;
                        string[]         missingModules   = null;

                        for (int retries = 3; retries > 0; --retries)
                        {
                            try {
                                existingDatabase = GetExistingDatabase(DatabasePath);
                                break;
                            } catch (UnauthorizedAccessException) {
                            } catch (IOException) {
                            }
                            Thread.Sleep(100);
                        }

                        if (existingDatabase == null)
                        {
                            // This will either succeed or throw again. If it throws
                            // then the error is reported to the user.
                            existingDatabase = GetExistingDatabase(DatabasePath);
                        }

                        for (int retries = 3; retries > 0; --retries)
                        {
                            try {
                                missingModules = GetMissingModules(existingDatabase);
                                break;
                            } catch (UnauthorizedAccessException) {
                            } catch (IOException) {
                            }
                            Thread.Sleep(100);
                        }

                        if (missingModules == null)
                        {
                            // This will either succeed or throw again. If it throws
                            // then the error is reported to the user.
                            missingModules = GetMissingModules(existingDatabase);
                        }

                        if (missingModules.Length > 0)
                        {
                            var oldModules = _missingModules;
                            if (oldModules == null ||
                                oldModules.Length != missingModules.Length ||
                                !oldModules.SequenceEqual(missingModules))
                            {
                            }
                            _missingModules = missingModules;
                        }
                        else
                        {
                            _missingModules = null;
                        }
                    }
                    _isCurrentException = null;
                } catch (Exception ex) {
                    // Report the exception text as the reason.
                    _isCurrentException = ex.ToString();
                    _missingModules     = null;
                } finally {
                    _isCheckingDatabase = false;
                }
            }

            OnIsCurrentChanged();
        }
 /// <summary>
 /// Creates a new interpreter factory with the specified database. This
 /// factory is suitable for analysis, but not execution.
 /// </summary>
 public static PythonInterpreterFactoryWithDatabase CreateAnalysisInterpreterFactory(
     Version languageVersion,
     PythonTypeDatabase database) {
     return new AnalysisOnlyInterpreterFactory(languageVersion, database);
 }
        /// <summary>
        /// Clears any cached type databases and raises the
        /// <see cref="NewDatabaseAvailable"/> event.
        /// </summary>
        protected void OnNewDatabaseAvailable() {
            _typeDb = null;
            _typeDbWithoutPackages = null;

            var evt = NewDatabaseAvailable;
            if (evt != null) {
                evt(this, EventArgs.Empty);
            }
        }
        /// <summary>
        /// Returns the database for this factory. This database may be shared
        /// between callers and should be cloned before making modifications.
        /// 
        /// This function never returns null.
        /// </summary>
        public PythonTypeDatabase GetCurrentDatabase() {
            if (_typeDb == null || _typeDb.DatabaseDirectory != DatabasePath) {
                _typeDb = MakeTypeDatabase(DatabasePath) ??
                    PythonTypeDatabase.CreateDefaultTypeDatabase(this);
            }

            return _typeDb;
        }
 /// <summary>
 /// Creates a new interpreter factory with the specified database. This
 /// factory is suitable for analysis, but not execution.
 /// </summary>
 public static PythonInterpreterFactoryWithDatabase CreateAnalysisInterpreterFactory(
     Version languageVersion,
     PythonTypeDatabase database)
 {
     return(new AnalysisOnlyInterpreterFactory(languageVersion, database));
 }
 public DatabaseReplacedEventArgs(PythonTypeDatabase newDatabase) {
     _newDatabase = newDatabase;
 }
        /// <summary>
        /// Sets up a weak reference for notification of when the shared database
        /// has become corrupted.  Doesn't keep the listening database alive.
        /// </summary>
        public void ListenForCorruptDatabase(PythonTypeDatabase db) {
            lock (_corruptListeners) {
                for (int i = 0; i < _corruptListeners.Count; i++) {
                    var target = _corruptListeners[i].Target;
                    if (target == null) {
                        _corruptListeners[i].Target = db;
                        return;
                    }
                }

                _corruptListeners.Add(new WeakReference(db));
            }
        }