示例#1
0
        public async Task NestedClasses()
        {
            const string code     = @"
x = 'str'

class A:
    def methodA(self):
        return True

class B:
    x: int

    class C:
        def __init__(self):
            self.y = 1
        def methodC(self):
            return False
        
    def methodB1(self):
        return self.C()

    def methodB2(self):
        return self.C().y

c = B().methodB1()
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);
            var json  = ToJson(model);

            Baseline.CompareToFile(BaselineFileName, json);
        }
示例#2
0
        public async Task PositionalOnly()
        {
            const string code     = @"
x = 'str'

class C:
    x: int
    def __init__(self):
        self.y = 1

    def method(self, x, /, y=True):
        return func()

    @property
    def prop(self) -> int:
        return x

def func():
    return 2.0

c = C()
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.Required_Python38X);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            using (var dbModule = CreateDbModule(model, analysis.Document.FilePath)) {
                dbModule.Should().HaveSameMembersAs(analysis.Document);
            }
        }
        public async Task Requests()
        {
            const string code     = @"
import requests
x = requests.get('microsoft.com')
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);

            var v = analysis.GlobalScope.Variables["requests"];

            v.Should().NotBeNull();
            if (v.Value.GetPythonType <IPythonModule>().ModuleType == ModuleType.Unresolved)
            {
                Assert.Inconclusive("'requests' package is not installed.");
            }

            var rq    = analysis.Document.Interpreter.ModuleResolution.GetImportedModule("requests");
            var model = ModuleModel.FromAnalysis(rq.Analysis, Services, AnalysisCachingLevel.Library);

            var u = model.UniqueId;

            u.Should().Contain("(").And.EndWith(")");
            var open = u.IndexOf('(');

            // Verify this looks like a version.
            new Version(u.Substring(open + 1, u.IndexOf(')') - open - 1));

            await CompareBaselineAndRestoreAsync(model, rq);
        }
        public async Task SmokeTest()
        {
            const string code     = @"
x = 'str'

class C:
    x: int
    def __init__(self):
        self.y = 1
        
    def method(self):
        return func()

    @property
    def prop(self) -> int:
        return x

def func():
    return 2.0

c = C()
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);
            var json  = ToJson(model);

            Baseline.CompareToFile(BaselineFileName, json);
        }
示例#5
0
        public async Task GenericClass()
        {
            const string code     = @"
from typing import Generic, TypeVar, Dict

K = TypeVar('K')
V = TypeVar('V')

class A(Generic[K, V], Dict[K, V]):
    def key(self) -> K:
        return K

    def value(self):
        return V

x = A(1, 'a')
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            //var json = ToJson(model);
            //Baseline.CompareToFile(BaselineFileName, json);

            using (var dbModule = CreateDbModule(model, analysis.Document.FilePath)) {
                dbModule.Should().HaveSameMembersAs(analysis.Document);
            }
        }
示例#6
0
        public async Task MemberLocations()
        {
            const string code     = @"
x = 'str'

def sum(a, b):
    return a + b

class B:
    x: int

    class C:
        def __init__(self):
            pass
        def methodC(self):
            pass

    @property
    def propertyB(self):
        return 1

    def methodB2(self):
        return 2
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            //var json = ToJson(model);
            //Baseline.CompareToFile(BaselineFileName, json);

            using (var dbModule = new PythonDbModule(model, analysis.Document.FilePath, Services)) {
                dbModule.Construct(model);

                var sum = dbModule.GetMember("sum") as IPythonFunctionType;
                sum.Should().NotBeNull();
                sum.Definition.Span.Should().Be(4, 5, 4, 8);

                var b = dbModule.GetMember("B") as IPythonClassType;
                b.Should().NotBeNull();
                b.Definition.Span.Should().Be(7, 7, 7, 8);

                var c = b.GetMember("C") as IPythonClassType;
                c.Should().NotBeNull();
                c.Definition.Span.Should().Be(10, 11, 10, 12);

                var methodC = c.GetMember("methodC") as IPythonFunctionType;
                methodC.Should().NotBeNull();
                methodC.Definition.Span.Should().Be(13, 13, 13, 20);

                var propertyB = b.GetMember("propertyB") as IPythonPropertyType;
                propertyB.Should().NotBeNull();
                propertyB.Definition.Span.Should().Be(17, 9, 17, 18);

                var methodB2 = b.GetMember("methodB2") as IPythonFunctionType;
                methodB2.Should().NotBeNull();
                methodB2.Definition.Span.Should().Be(20, 9, 20, 17);
            }
        }
示例#7
0
        internal async Task <ModuleModel> GetModelAsync(string code)
        {
            var analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            model.FilePath = null;
            return(model);
        }
示例#8
0
        private void StoreModuleAnalysis(IDocumentAnalysis analysis, CancellationToken cancellationToken = default)
        {
            var cachingLevel = GetCachingLevel();

            if (cachingLevel == AnalysisCachingLevel.None)
            {
                return;
            }

            var model = ModuleModel.FromAnalysis(analysis, _services, cachingLevel);

            if (model == null)
            {
                // Caching level setting does not permit this module to be persisted.
                return;
            }

            Exception ex = null;

            for (var retries = 50; retries > 0; --retries)
            {
                lock (_lock) {
                    cancellationToken.ThrowIfCancellationRequested();
                    try {
                        if (!_fs.DirectoryExists(_databaseFolder))
                        {
                            _fs.CreateDirectory(_databaseFolder);
                        }

                        cancellationToken.ThrowIfCancellationRequested();
                        using (var db = new LiteDatabase(Path.Combine(_databaseFolder, $"{model.UniqueId}.db"))) {
                            var modules = db.GetCollection <ModuleModel>("modules");
                            modules.Upsert(model);
                            return;
                        }
                    } catch (Exception ex1) when(ex1 is IOException || ex1 is UnauthorizedAccessException)
                    {
                        ex = ex1;
                        Thread.Sleep(10);
                    } catch (Exception ex2) {
                        ex = ex2;
                        break;
                    }
                }
            }

            if (ex != null)
            {
                _log?.Log(System.Diagnostics.TraceEventType.Warning, $"Unable to write analysis of {model.Name} to database. Exception {ex.Message}");
                if (ex.IsCriticalException())
                {
                    throw ex;
                }
            }
        }
        public async Task Builtins()
        {
            var analysis = await GetAnalysisAsync(string.Empty);

            var builtins = analysis.Document.Interpreter.ModuleResolution.BuiltinsModule;
            var model    = ModuleModel.FromAnalysis(builtins.Analysis, Services, AnalysisCachingLevel.Library);

            var json = ToJson(model);

            Baseline.CompareToFile(BaselineFileName, json);

            var dbModule = new PythonDbModule(model, null, Services);

            dbModule.Should().HaveSameMembersAs(builtins);
        }
        public async Task StoreModuleAnalysisAsync(IDocumentAnalysis analysis, bool immediate = false, CancellationToken cancellationToken = default)
        {
            var cachingLevel = GetCachingLevel();

            if (cachingLevel == AnalysisCachingLevel.None)
            {
                return;
            }

            var model = await Task.Run(() => ModuleModel.FromAnalysis(analysis, _services, cachingLevel), cancellationToken);

            if (model != null && !cancellationToken.IsCancellationRequested)
            {
                await _cacheWriter.EnqueueModel(model, immediate, cancellationToken);
            }
        }
        private async Task TestModule(string name)
        {
            var analysis = await GetAnalysisAsync($"import {name}", PythonVersions.Python37_x64);

            var m = analysis.Document.Interpreter.ModuleResolution.GetImportedModule(name);

            if (m == null || m.ModuleType == ModuleType.Unresolved)
            {
                Assert.Inconclusive($"Module {name} is not installed or otherwise could not be imported.");
                return;
            }

            var model = ModuleModel.FromAnalysis(m.Analysis, Services, AnalysisCachingLevel.Library);

            model.Should().NotBeNull($"Module {name} is either not installed or cannot be cached");

            await CompareBaselineAndRestoreAsync(model, m);
        }
        public async Task ClassesWithSuper()
        {
            const string code     = @"
class A:
    def methodA(self):
        return True

class B(A):
    def methodB(self):
        return super()
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            using (var dbModule = CreateDbModule(model, analysis.Document.FilePath)) {
                dbModule.Should().HaveSameMembersAs(analysis.Document);
            }
        }
示例#13
0
        public async Task PrivateMembers()
        {
            const string code     = @"
class A:
    _x = 1

    def _methodA(self):
        return True

    @classmethod
    def _methodB(self):
        return True
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            await CompareBaselineAndRestoreAsync(model, analysis.Document);
        }
示例#14
0
        public async Task ClassOwnDocumentation()
        {
            const string code     = @"
class A:
    '''class A doc'''

class B(A):
    def __init__(self):
    '''__init__ doc'''
        return
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);
            var json  = ToJson(model);

            // In JSON, class A should have 'class A doc' documentation while B should have none.
            Baseline.CompareToFile(BaselineFileName, json);
        }
        public async Task VersionHandling(bool is3x)
        {
            const string code     = @"
if sys.version_info >= (3, 0):
    def func(a, b, c): ...
else:
    def func(a): ...
";
            var          analysis = await GetAnalysisAsync(code, is3x?PythonVersions.LatestAvailable3X : PythonVersions.LatestAvailable2X);

            analysis.Should().HaveFunction("func")
            .Which.Should().HaveSingleOverload()
            .Which.Should().HaveParameters(is3x ? new[] { "a", "b", "c" } : new[] { "a" });

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);
            var json  = ToJson(model);

            Baseline.CompareToFile(GetBaselineFileNameWithSuffix(is3x ? "3" : "2"), json);
        }
示例#16
0
        public async Task ForwardDeclarations()
        {
            const string code     = @"
x = 'str'

class A:
    def methodA1(self):
        return B()

    def methodA2(self):
        return func()

class B:
    class C:
        def methodC(self):
            return func()
        
    def methodB1(self):
        def a():
            return 1
        return a

def func():
    return 1

a = B().methodB1()
b = A().methodA1()
";
            var          analysis = await GetAnalysisAsync(code);

            analysis.Should().HaveVariable("a").Which.Should().HaveType("a");
            analysis.Should().HaveVariable("b").Which.Should().HaveType("B");

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            //var json = ToJson(model);
            //Baseline.CompareToFile(BaselineFileName, json);

            using (var dbModule = CreateDbModule(model, analysis.Document.FilePath)) {
                dbModule.Should().HaveSameMembersAs(analysis.Document);
            }
        }
示例#17
0
        public async Task Logging()
        {
            const string code     = @"
import logging
logging.critical()
";
            var          analysis = await GetAnalysisAsync(code);

            var logging = analysis.Document.Interpreter.ModuleResolution.GetImportedModule("logging");
            var model   = ModuleModel.FromAnalysis(logging.Analysis, Services, AnalysisCachingLevel.Library);

            await CompareRestoreAsync(model, logging);

            using (var m = CreateDbModule(model, logging.FilePath)) {
                var critical = m.GetMember("critical") as IPythonFunctionType;
                critical.Should().NotBeNull();

                var span = critical.Definition.Span;
                span.Start.Line.Should().BeGreaterThan(1000);
                (span.End.Column - span.Start.Column).Should().Be("critical".Length);
            }
        }
        public async Task NamedTupleWithSuper()
        {
            const string code     = @"
from typing import NamedTuple

Point = NamedTuple('Point', ['x', 'y'])

class ChildPoint(Point):
    def foo(self):
        pass

p = ChildPoint()

x = super(ChildPoint, p)
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            using (var dbModule = CreateDbModule(model, analysis.Document.FilePath)) {
                dbModule.Should().HaveSameMembersAs(analysis.Document);
            }
        }
        public async Task GlobalSuper()
        {
            const string code     = @"
class Baze:
    def baze_foo(self):
        pass

class Derived(Baze):
    def foo(self):
        pass

d = Derived()

x = super(Derived, d)
";
            var          analysis = await GetAnalysisAsync(code);

            var model = ModuleModel.FromAnalysis(analysis, Services, AnalysisCachingLevel.Library);

            using (var dbModule = CreateDbModule(model, analysis.Document.FilePath)) {
                dbModule.Should().HaveSameMembersAs(analysis.Document);
            }
        }