From 40c24df465333be79846c23e2bf50c6112363e7f Mon Sep 17 00:00:00 2001 From: Alexander Sher Date: Thu, 20 Sep 2018 13:32:38 -0700 Subject: [PATCH] Port PR from PTVS: https://github.com/Microsoft/PTVS/pull/4716 --- src/Analysis/Engine/Impl/Analyzer/DDG.cs | 38 +++++++++++++----- src/Analysis/Engine/Test/InheritanceTests.cs | 42 ++++++++++++++++++++ 2 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 src/Analysis/Engine/Test/InheritanceTests.cs diff --git a/src/Analysis/Engine/Impl/Analyzer/DDG.cs b/src/Analysis/Engine/Impl/Analyzer/DDG.cs index f17c24ad6..ed840aa19 100644 --- a/src/Analysis/Engine/Impl/Analyzer/DDG.cs +++ b/src/Analysis/Engine/Impl/Analyzer/DDG.cs @@ -454,13 +454,13 @@ private bool TryImportModule(string modName, bool forceAbsolute, out ModuleRefer return false; } - internal List LookupBaseMethods(string name, IEnumerable bases, Node node, AnalysisUnit unit) { + internal List LookupBaseMethods(string name, IEnumerable mro, Node node, AnalysisUnit unit) { var result = new List(); - foreach (var b in bases) { - foreach (var curType in b) { - var klass = curType as BuiltinClassInfo; - if (klass != null) { - var value = klass.GetMember(node, unit, name); + foreach (var @class in mro.Skip(1)) { + foreach (var curType in @class) { + bool isClass = curType is ClassInfo || curType is BuiltinClassInfo; + if (isClass) { + var value = curType.GetMember(node, unit, name); if (value != null) { result.AddRange(value); } @@ -470,7 +470,6 @@ internal List LookupBaseMethods(string name, IEnumerable()) { + var baseAnalysisUnit = (FunctionAnalysisUnit)baseFunction.AnalysisUnit; + baseAnalysisUnit.ReturnValue.AddTypes(_unit, lookupRes); + } } return true; } diff --git a/src/Analysis/Engine/Test/InheritanceTests.cs b/src/Analysis/Engine/Test/InheritanceTests.cs new file mode 100644 index 000000000..052b425e0 --- /dev/null +++ b/src/Analysis/Engine/Test/InheritanceTests.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Python.LanguageServer.Implementation; +using Microsoft.PythonTools.Analysis.FluentAssertions; +using Microsoft.PythonTools.Interpreter; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TestUtilities; + +namespace Microsoft.PythonTools.Analysis { + [TestClass] + public class InheritanceTests { + public TestContext TestContext { get; set; } + + [TestInitialize] + public void TestInitialize() => TestEnvironmentImpl.TestInitialize($"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}"); + + [TestCleanup] + public void TestCleanup() => TestEnvironmentImpl.TestCleanup(); + + [TestMethod] + public async Task AbstractMethodReturnTypeIgnored() { + var code = @"import abc +class A: + @abc.abstractmethod + def virt(): + pass +class B(A): + def virt(): + return 42 +a = A() +b = a.virt()"; + + using (var server = await new Server().InitializeAsync(PythonVersions.Required_Python36X)) { + var analysis = await server.OpenDefaultDocumentAndGetAnalysisAsync(code); + + analysis.Should().HaveVariable("b").OfType(BuiltinTypeId.Int); + } + } + } +}