コード例 #1
0
        public async Task ReloadAsync(CancellationToken cancellationToken = default)
        {
            ModuleCache = new ModuleCache(_interpreter, _services);

            _pathResolver = new PathResolver(_interpreter.LanguageVersion);

            var addedRoots = _pathResolver.SetRoot(_root);

            ReloadModulePaths(addedRoots);

            var interpreterPaths = await GetSearchPathsAsync(cancellationToken);

            addedRoots = _pathResolver.SetInterpreterSearchPaths(interpreterPaths);
            ReloadModulePaths(addedRoots);

            addedRoots = _pathResolver.SetUserSearchPaths(_interpreter.Configuration.SearchPaths);
            ReloadModulePaths(addedRoots);
        }
コード例 #2
0
        internal async Task LoadBuiltinTypesAsync(CancellationToken cancellationToken = default)
        {
            // Add names from search paths
            await ReloadAsync(cancellationToken);

            // Initialize built-in
            var moduleName = BuiltinTypeId.Unknown.GetModuleName(_interpreter.LanguageVersion);
            var modulePath = ModuleCache.GetCacheFilePath(_interpreter.Configuration.InterpreterPath ?? "python.exe");

            var b = new BuiltinsPythonModule(moduleName, modulePath, _services);

            _modules[BuiltinModuleName] = BuiltinsModule = b;
            await b.LoadAndAnalyzeAsync(cancellationToken);

            // Add built-in module names
            var builtinModuleNamesMember = BuiltinsModule.GetAnyMember("__builtin_module_names__");

            if (builtinModuleNamesMember.TryGetConstant <string>(out var s))
            {
                var builtinModuleNames = s.Split(',').Select(n => n.Trim());
                _pathResolver.SetBuiltins(builtinModuleNames);
            }
        }
コード例 #3
0
        private async Task <TryImportModuleResult> TryImportModuleAsync(string name, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(name))
            {
                return(TryImportModuleResult.ModuleNotFound);
            }
            if (name == BuiltinModuleName)
            {
                return(new TryImportModuleResult(BuiltinsModule));
            }

            Debug.Assert(!name.EndsWithOrdinal("."), $"{name} should not end with '.'");
            // Return any existing module
            if (_modules.TryGetValue(name, out var module) && module != null)
            {
                if (module is SentinelModule)
                {
                    // TODO: we can't just wait here or we hang. There are two cases:
                    //   a. Recursion on the same analysis chain (A -> B -> A)
                    //   b. Call from another chain (A -> B -> C and D -> B -> E).
                    // TODO: Both should be resolved at the dependency chain level.
                    _log?.Log(TraceEventType.Warning, $"Recursive import: {name}");
                }
                return(new TryImportModuleResult(module));
            }

            // Set up a sentinel so we can detect recursive imports
            var sentinelValue = new SentinelModule(name, _services);

            if (!_modules.TryAdd(name, sentinelValue))
            {
                // Try to get the new module, in case we raced with a .Clear()
                if (_modules.TryGetValue(name, out module) && !(module is SentinelModule))
                {
                    return(new TryImportModuleResult(module));
                }
                // If we reach here, the race is too complicated to recover
                // from. Signal the caller to try importing again.
                _log?.Log(TraceEventType.Warning, $"Retry import: {name}");
                return(TryImportModuleResult.NeedRetry);
            }

            // Do normal searches
            try {
                module = await ImportFromSearchPathsAsync(name, cancellationToken).ConfigureAwait(false);
            } catch (OperationCanceledException) {
                _log?.Log(TraceEventType.Error, $"Import timeout {name}");
                return(TryImportModuleResult.Timeout);
            }

            module = module ?? await ModuleCache.ImportFromCacheAsync(name, cancellationToken);

            // Replace our sentinel
            if (!_modules.TryUpdate(name, module, sentinelValue))
            {
                // Try to get the new module, in case we raced
                if (_modules.TryGetValue(name, out module) && !(module is SentinelModule))
                {
                    return(new TryImportModuleResult(module));
                }
                // If we reach here, the race is too complicated to recover
                // from. Signal the caller to try importing again.
                _log?.Log(TraceEventType.Warning, $"Retry import: {name}");
                return(TryImportModuleResult.NeedRetry);
            }

            return(new TryImportModuleResult(module));
        }