public static async Task <Server> InitializeAsync(this Server server, InterpreterConfiguration configuration, Uri rootUri = null, IEnumerable <string> searchPaths = null)
        {
            configuration.AssertInstalled();

            server.OnLogMessage += Server_OnLogMessage;
            var properties = new InterpreterFactoryCreationOptions {
                TraceLevel   = System.Diagnostics.TraceLevel.Verbose,
                DatabasePath = TestData.GetAstAnalysisCachePath(configuration.Version)
            }.ToDictionary();

            configuration.WriteToDictionary(properties);

            await server.Initialize(new InitializeParams {
                rootUri = rootUri,
                initializationOptions = new PythonInitializationOptions {
                    interpreter = new PythonInitializationOptions.Interpreter {
                        assembly   = typeof(AstPythonInterpreterFactory).Assembly.Location,
                        typeName   = typeof(AstPythonInterpreterFactory).FullName,
                        properties = properties
                    },
                    analysisUpdates = true,
                    searchPaths     = searchPaths?.ToArray() ?? Array.Empty <string>(),
                    traceLogging    = true,
                },
                capabilities = new ClientCapabilities {
                    python = new PythonClientCapabilities {
                        liveLinting = true,
                    }
                }
            }, CancellationToken.None);

            return(server);
        }
        private async Task BuiltinScrape(InterpreterConfiguration configuration)
        {
            configuration.AssertInstalled();
            var moduleUri       = TestData.GetDefaultModuleUri();
            var moduleDirectory = Path.GetDirectoryName(moduleUri.LocalPath);

            var services = await CreateServicesAsync(moduleDirectory, configuration);

            var interpreter = services.GetService <IPythonInterpreter>();

            var mod = await interpreter.ModuleResolution.ImportModuleAsync(interpreter.ModuleResolution.BuiltinModuleName, new CancellationTokenSource(5000).Token);

            Assert.IsInstanceOfType(mod, typeof(BuiltinsPythonModule));
            var modPath = interpreter.ModuleResolution.ModuleCache.GetCacheFilePath(interpreter.Configuration.InterpreterPath);

            var doc    = mod as IDocument;
            var errors = doc.GetParseErrors().ToArray();

            foreach (var err in errors)
            {
                Console.WriteLine(err);
            }
            Assert.AreEqual(0, errors.Count(), "Parse errors occurred");

            var ast = await doc.GetAstAsync();

            var seen = new HashSet <string>();

            foreach (var stmt in ((SuiteStatement)ast.Body).Statements)
            {
                if (stmt is ClassDefinition cd)
                {
                    Assert.IsTrue(seen.Add(cd.Name), $"Repeated use of {cd.Name} at index {cd.StartIndex} in {modPath}");
                }
                else if (stmt is FunctionDefinition fd)
                {
                    Assert.IsTrue(seen.Add(fd.Name), $"Repeated use of {fd.Name} at index {fd.StartIndex} in {modPath}");
                }
                else if (stmt is AssignmentStatement assign && assign.Left.FirstOrDefault() is NameExpression n)
                {
                    Assert.IsTrue(seen.Add(n.Name), $"Repeated use of {n.Name} at index {n.StartIndex} in {modPath}");
                }
            }

            // Ensure we can get all the builtin types
            foreach (BuiltinTypeId v in Enum.GetValues(typeof(BuiltinTypeId)))
            {
                var type = interpreter.GetBuiltinType(v);
                type.Should().NotBeNull().And.BeAssignableTo <IPythonType>($"Did not find {v}");
                type.IsBuiltin.Should().BeTrue();
            }

            // Ensure we cannot see or get builtin types directly
            mod.GetMemberNames().Should().NotContain(Enum.GetNames(typeof(BuiltinTypeId)).Select(n => $"__{n}"));

            foreach (var id in Enum.GetNames(typeof(BuiltinTypeId)))
            {
                mod.GetMember($"__{id}").Should().BeNull(id);
            }
        }
        internal async Task <IServiceManager> CreateServicesAsync(string root, InterpreterConfiguration configuration = null)
        {
            configuration = configuration ?? PythonVersions.LatestAvailable;
            configuration.AssertInstalled();
            Trace.TraceInformation("Cache Path: " + configuration.ModuleCachePath);
            configuration.ModuleCachePath = TestData.GetAstAnalysisCachePath(configuration.Version, true);
            configuration.SearchPaths     = new[] { GetAnalysisTestDataFilesPath() };
            configuration.TypeshedPath    = TestData.GetDefaultTypeshedPath();

            var sm = CreateServiceManager();

            sm.AddService(new DiagnosticsService());

            TestLogger.Log(TraceEventType.Information, "Create TestDependencyResolver");
            var dependencyResolver = new TestDependencyResolver();

            sm.AddService(dependencyResolver);

            TestLogger.Log(TraceEventType.Information, "Create PythonAnalyzer");
            var analyzer = new PythonAnalyzer(sm);

            sm.AddService(analyzer);

            TestLogger.Log(TraceEventType.Information, "Create PythonInterpreter");
            var interpreter = await PythonInterpreter.CreateAsync(configuration, root, sm);

            sm.AddService(interpreter);

            TestLogger.Log(TraceEventType.Information, "Create RunningDocumentTable");
            var documentTable = new RunningDocumentTable(root, sm);

            sm.AddService(documentTable);

            return(sm);
        }
        protected async Task <Server> CreateServerAsync(InterpreterConfiguration configuration = null, Uri rootUri = null)
        {
            configuration = configuration ?? PythonVersions.LatestAvailable2X ?? PythonVersions.LatestAvailable3X;
            configuration.AssertInstalled();

            _server = await new Server().InitializeAsync(configuration, rootUri);
            _server.Analyzer.EnableDiagnostics = true;
            _server.Analyzer.Limits            = GetLimits();

            return(_server);
        }
        public async Task <Server> CreateServer(Uri rootUri, InterpreterConfiguration configuration = null, Dictionary <Uri, PublishDiagnosticsEventArgs> diagnosticEvents = null)
        {
            configuration = configuration ?? Default;
            configuration.AssertInstalled();

            var sm = new ServiceManager();

            sm.AddService(new TestLogger());
            var s = new Server(sm);

            var properties = new InterpreterFactoryCreationOptions {
                TraceLevel   = System.Diagnostics.TraceLevel.Verbose,
                DatabasePath = TestData.GetAstAnalysisCachePath(configuration.Version)
            }.ToDictionary();

            configuration.WriteToDictionary(properties);

            await s.Initialize(new InitializeParams {
                rootUri = rootUri,
                initializationOptions = new PythonInitializationOptions {
                    interpreter = new PythonInitializationOptions.Interpreter {
                        assembly   = typeof(AstPythonInterpreterFactory).Assembly.Location,
                        typeName   = typeof(AstPythonInterpreterFactory).FullName,
                        properties = properties
                    },
                    testEnvironment = true,
                    analysisUpdates = true,
                    traceLogging    = true,
                },
                capabilities = new ClientCapabilities {
                    python = new PythonClientCapabilities {
                        liveLinting = true,
                    }
                }
            }, CancellationToken.None);

            if (diagnosticEvents != null)
            {
                s.OnPublishDiagnostics += (sender, e) => { lock (diagnosticEvents) diagnosticEvents[e.uri] = e; };
            }

            if (rootUri != null)
            {
                await LoadFromDirectoryAsync(s, rootUri.LocalPath).ConfigureAwait(false);

                await s.WaitForCompleteAnalysisAsync(CancellationToken.None).ConfigureAwait(false);
            }

            return(s);
        }
        protected async Task <IServiceManager> CreateServicesAsync(string root, InterpreterConfiguration configuration, IServiceManager sm = null)
        {
            configuration = configuration ?? PythonVersions.LatestAvailable;
            configuration.AssertInstalled();
            Trace.TraceInformation("Cache Path: " + configuration.DatabasePath);
            configuration.DatabasePath = TestData.GetAstAnalysisCachePath(configuration.Version, true);
            configuration.SearchPaths  = new[] { GetAnalysisTestDataFilesPath() };
            configuration.TypeshedPath = TestData.GetDefaultTypeshedPath();

            sm = sm ?? CreateServiceManager();

            var clientApp = Substitute.For <IClientApplication>();

            sm.AddService(clientApp);

            var idle = Substitute.For <IIdleTimeService>();

            sm.AddService(idle);

            var ds = GetDiagnosticsService(Services);

            if (ds != null)
            {
                sm.AddService(ds);
            }

            TestLogger.Log(TraceEventType.Information, "Create PythonAnalyzer");
            var analyzer = new PythonAnalyzer(sm);

            sm.AddService(analyzer);

            TestLogger.Log(TraceEventType.Information, "Create PythonInterpreter");
            var interpreter = await PythonInterpreter.CreateAsync(configuration, root, sm);

            sm.AddService(interpreter);

            TestLogger.Log(TraceEventType.Information, "Create RunningDocumentTable");
            var documentTable = new RunningDocumentTable(sm);

            sm.AddService(documentTable);

            return(sm);
        }
Exemple #7
0
        private void TestMutateStdLib(InterpreterConfiguration configuration)
        {
            configuration.AssertInstalled();

            for (int i = 0; i < 100; i++)
            {
                int seed   = (int)DateTime.Now.Ticks;
                var random = new Random(seed);
                Console.WriteLine("Seed == " + seed);


                Console.WriteLine("Testing version {0} {1}", configuration.Version, configuration.LibraryPath);
                int      ran = 0, succeeded = 0;
                string[] files;
                try {
                    files = Directory.GetFiles(configuration.LibraryPath);
                } catch (DirectoryNotFoundException) {
                    continue;
                }

                foreach (var file in files)
                {
                    try {
                        if (file.EndsWith(".py"))
                        {
                            ran++;
                            TestOneFileMutated(file, configuration.Version.ToLanguageVersion(), random);
                            succeeded++;
                        }
                    } catch (Exception e) {
                        Console.WriteLine(e);
                        Console.WriteLine("Failed: {0}", file);
                        break;
                    }
                }

                Assert.AreEqual(ran, succeeded);
            }
        }
Exemple #8
0
        protected async Task <IServiceManager> CreateServicesAsync(string root, InterpreterConfiguration configuration, string stubCacheFolderPath = null, IServiceManager sm = null, string[] searchPaths = null)
        {
            configuration = configuration ?? PythonVersions.LatestAvailable;
            configuration.AssertInstalled();
            Trace.TraceInformation("Cache Path: " + stubCacheFolderPath);

            searchPaths = searchPaths ?? new[] { GetAnalysisTestDataFilesPath() };
            var typeshedPath = TestData.GetDefaultTypeshedPath();

            sm = sm ?? CreateServiceManager();

            sm.AddService(Substitute.For <IClientApplication>())
            .AddService(Substitute.For <IIdleTimeService>());

            var ds = GetDiagnosticsService(Services);

            if (ds != null)
            {
                sm.AddService(ds);
            }

            TestLogger.Log(TraceEventType.Information, "Create PythonAnalyzer");

            CacheService.Register(sm, stubCacheFolderPath);
            var analyzer = new PythonAnalyzer(sm);

            sm.AddService(analyzer);

            TestLogger.Log(TraceEventType.Information, "Create PythonInterpreter");
            var interpreter = await PythonInterpreter.CreateAsync(configuration, root, sm, typeshedPath, searchPaths.ToImmutableArray());

            sm.AddService(interpreter);

            TestLogger.Log(TraceEventType.Information, "Create RunningDocumentTable");
            sm.AddService(new RunningDocumentTable(sm));

            return(sm);
        }
        private async Task CompiledBuiltinScrapeAsync(InterpreterConfiguration configuration)
        {
            configuration.AssertInstalled();

            var moduleUri       = TestData.GetDefaultModuleUri();
            var moduleDirectory = Path.GetDirectoryName(moduleUri.LocalPath);

            var services = await CreateServicesAsync(moduleDirectory, configuration);

            var interpreter = services.GetService <IPythonInterpreter>();
            var fs          = services.GetService <IFileSystem>();

            // TODO: this is Windows only
            var dllsDir = Path.Combine(Path.GetDirectoryName(interpreter.Configuration.LibraryPath), "DLLs");

            if (!Directory.Exists(dllsDir))
            {
                Assert.Inconclusive("Configuration does not have DLLs");
            }

            var report           = new List <string>();
            var permittedImports = interpreter.LanguageVersion.Is2x() ?
                                   new[] { interpreter.ModuleResolution.BuiltinModuleName, "exceptions" } :
            new[] { interpreter.ModuleResolution.BuiltinModuleName };

            var modules = new List <IPythonModule>();

            foreach (var pyd in PathUtils.EnumerateFiles(fs, dllsDir, "*", recurse: false).Select(f => f.FullName).Where(ModulePath.IsPythonFile))
            {
                var mp = ModulePath.FromFullPath(pyd);
                if (mp.IsDebug)
                {
                    continue;
                }

                Console.WriteLine(@"Importing {0} from {1}", mp.ModuleName, mp.SourceFile);
                modules.Add(interpreter.ModuleResolution.GetOrLoadModule(mp.ModuleName));
            }

            foreach (var mod in modules)
            {
                Assert.IsInstanceOfType(mod, typeof(CompiledPythonModule));

                await((StubCache)interpreter.ModuleResolution.StubCache).CacheWritingTask;
                var modPath = interpreter.ModuleResolution.StubCache.GetCacheFilePath(mod.FilePath);
                Assert.IsTrue(File.Exists(modPath), "No cache file created");

                var doc = (IDocument)mod;
                var ast = await doc.GetAstAsync();

                var errors = doc.GetParseErrors().ToArray();
                foreach (var err in errors)
                {
                    Console.WriteLine(err);
                }
                Assert.AreEqual(0, errors.Length, "Parse errors occurred");


                var imports = ((SuiteStatement)ast.Body).Statements
                              .OfType <ImportStatement>()
                              .SelectMany(s => s.Names)
                              .Select(n => n.MakeString())
                              .Except(permittedImports)
                              .ToArray();

                // We expect no imports (after excluding builtins)
                report.AddRange(imports.Select(n => $"{mod.Name} imported {n}"));
            }

            report.Should().BeEmpty();
        }
        private async Task FullStdLibTest(InterpreterConfiguration configuration, params string[] skipModules)
        {
            configuration.AssertInstalled();
            var moduleUri       = TestData.GetDefaultModuleUri();
            var moduleDirectory = Path.GetDirectoryName(moduleUri.LocalPath);

            var services = await CreateServicesAsync(moduleDirectory, configuration);

            var interpreter = services.GetService <IPythonInterpreter>();

            var pathResolver = interpreter.ModuleResolution.CurrentPathResolver;
            var modules      = pathResolver.GetAllImportableModuleNames()
                               .Select(n => pathResolver.GetModuleImportFromModuleName(n))
                               .ExcludeDefault()
                               .Where(i => i.RootPath.PathEquals(configuration.SitePackagesPath) || i.RootPath.PathEquals(configuration.LibraryPath))
                               .ToList();

            var skip = new HashSet <string>(skipModules);

            skip.UnionWith(new[] {
                @"matplotlib.backends._backend_gdk",
                @"matplotlib.backends._backend_gtkagg",
                @"matplotlib.backends._gtkagg",
                "test.test_pep3131",
                "test.test_unicode_identifiers",
                "test.test_super" // nonlocal syntax error
            });
            skip.UnionWith(modules.Select(m => m.FullName)
                           .Where(n => n.StartsWith(@"test.badsyntax") || n.StartsWith("test.bad_coding")));

            var anySuccess          = false;
            var anyExtensionSuccess = false;
            var anyExtensionSeen    = false;
            var anyParseError       = false;

            foreach (var m in skip)
            {
                ((MainModuleResolution)interpreter.ModuleResolution).AddUnimportableModule(m);
            }

            var set = modules
                      .Where(m => !skip.Contains(m.FullName))
                      .GroupBy(m => {
                var i = m.FullName.IndexOf('.');
                return(i <= 0 ? m.FullName : m.FullName.Remove(i));
            })
                      .SelectMany(g => g.Select(m => Tuple.Create(m, m.FullName)))
                      .ToArray();

            set = set.Where(x => x.Item2 != null && x.Item2.Contains("grammar")).ToArray();

            var sb = new StringBuilder();

            foreach (var r in set)
            {
                var module = interpreter.ModuleResolution.GetOrLoadModule(r.Item2);
                if (module != null)
                {
                    sb.AppendLine($"import {module.Name}");
                }
            }

            await GetAnalysisAsync(sb.ToString(), services);

            foreach (var r in set)
            {
                var modName = r.Item1;
                var mod     = interpreter.ModuleResolution.GetOrLoadModule(r.Item2);

                anyExtensionSeen |= modName.IsCompiled;
                switch (mod)
                {
                case null:
                    Trace.TraceWarning("failed to import {0} from {1}", modName.FullName, modName.ModulePath);
                    break;

                case CompiledPythonModule compiledPythonModule:
                    var errors = compiledPythonModule.GetParseErrors().ToArray();
                    if (errors.Any())
                    {
                        anyParseError = true;
                        Trace.TraceError("Parse errors in {0}", modName.ModulePath);
                        foreach (var e in errors)
                        {
                            Trace.TraceError(e.Message);
                        }
                    }
                    else
                    {
                        anySuccess           = true;
                        anyExtensionSuccess |= modName.IsCompiled;
                    }

                    break;

                case IPythonModule _: {
                    var filteredErrors = ((IDocument)mod).GetParseErrors().Where(e => !e.Message.Contains("encoding problem")).ToArray();
                    if (filteredErrors.Any())
                    {
                        // Do not fail due to errors in installed packages
                        if (!mod.FilePath.Contains("site-packages"))
                        {
                            anyParseError = true;
                        }
                        Trace.TraceError("Parse errors in {0}", modName.ModulePath);
                        foreach (var e in filteredErrors)
                        {
                            Trace.TraceError(e.Message);
                        }
                    }
                    else
                    {
                        anySuccess           = true;
                        anyExtensionSuccess |= modName.IsCompiled;
                    }

                    break;
                }
                }
            }
            Assert.IsTrue(anySuccess, "failed to import any modules at all");
            Assert.IsTrue(anyExtensionSuccess || !anyExtensionSeen, "failed to import all extension modules");
            Assert.IsFalse(anyParseError, "parse errors occurred");
        }
        private async Task BuiltinScrape(InterpreterConfiguration configuration, string stubCacheFolderPath = null)
        {
            configuration.AssertInstalled();
            var moduleUri       = TestData.GetDefaultModuleUri();
            var moduleDirectory = Path.GetDirectoryName(moduleUri.LocalPath);

            var services = await CreateServicesAsync(moduleDirectory, configuration, stubCacheFolderPath);

            var interpreter = services.GetService <IPythonInterpreter>();

            var mod = interpreter.ModuleResolution.GetOrLoadModule(interpreter.ModuleResolution.BuiltinModuleName);

            mod.Should().BeAssignableTo <BuiltinsPythonModule>();

            var stubCache = interpreter.ModuleResolution.StubCache;
            var modPath   = stubCache.GetCacheFilePath(interpreter.Configuration.InterpreterPath);

            // Verify that we are using correct database path.
            modPath.Should().StartWith(
                !string.IsNullOrEmpty(stubCacheFolderPath) ? stubCacheFolderPath : stubCache.StubCacheFolder
                );

            var doc = (IDocument)mod;
            await doc.GetAnalysisAsync();

            var errors = doc.GetParseErrors().ToArray();

            foreach (var err in errors)
            {
                Console.WriteLine(err);
            }

            errors.Should().BeEmpty("Parse errors occurred");

            var ast = await doc.GetAstAsync();

            var seen = new HashSet <string>();

            foreach (var stmt in ((SuiteStatement)ast.Body).Statements)
            {
                switch (stmt)
                {
                case ClassDefinition cd:
                    seen.Add(cd.Name).Should().BeTrue($"Repeated use of {cd.Name} at index {cd.StartIndex} in {modPath}");
                    break;

                case FunctionDefinition fd:
                    seen.Add(fd.Name).Should().BeTrue($"Repeated use of {fd.Name} at index {fd.StartIndex} in {modPath}");
                    break;

                case AssignmentStatement assign when assign.Left.FirstOrDefault() is NameExpression n:
                    seen.Add(n.Name).Should().BeTrue($"Repeated use of {n.Name} at index {n.StartIndex} in {modPath}");

                    break;
                }
            }

            // Ensure we can get all the builtin types
            foreach (BuiltinTypeId v in Enum.GetValues(typeof(BuiltinTypeId)))
            {
                var type = interpreter.GetBuiltinType(v);
                type.Should().NotBeNull().And.BeAssignableTo <IPythonType>($"Did not find {v}");
                type.IsBuiltin.Should().BeTrue();
            }

            // Ensure we cannot see or get builtin types directly
            mod.GetMemberNames().Should().NotContain(Enum.GetNames(typeof(BuiltinTypeId)).Select(n => $"__{n}"));

            foreach (var id in Enum.GetNames(typeof(BuiltinTypeId)))
            {
                mod.GetMember($"__{id}").Should().BeNull(id);
            }
        }