diff --git a/AUTHORS.md b/AUTHORS.md index 23327f84c..9109c65c2 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -28,6 +28,7 @@ - Christoph Gohlke ([@cgohlke](https://github.com/cgohlke)) - Christopher Bremner ([@chrisjbremner](https://github.com/chrisjbremner)) - Christopher Pow ([@christopherpow](https://github.com/christopherpow)) +- Daniel Abrahamsson ([@danabr](https://github.com/danabr)) - Daniel Fernandez ([@fdanny](https://github.com/fdanny)) - Daniel Santana ([@dgsantana](https://github.com/dgsantana)) - Dave Hirschfeld ([@dhirschfeld](https://github.com/dhirschfeld)) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ba1594ca..0505ed540 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ details about the cause of the failure - Fix incorrect dereference of wrapper object in `tp_repr`, which may result in a program crash - Fix incorrect dereference in params array handling - Fix `object[]` parameters taking precedence when should not in overload resolution +- Fix methods and properties of explictly implemented interfaces being invisible ## [2.5.0][] - 2020-06-14 diff --git a/src/runtime/classmanager.cs b/src/runtime/classmanager.cs index 0b084a49d..3110df25e 100644 --- a/src/runtime/classmanager.cs +++ b/src/runtime/classmanager.cs @@ -241,32 +241,29 @@ private static ClassInfo GetClassInfo(Type type) } } - if (type.IsInterface) + // Interface inheritance seems to be a different animal: + // more contractual, less structural. Thus, a Type that + // represents an interface that inherits from another + // interface does not return the inherited interface's + // methods in GetMembers. For example ICollection inherits + // from IEnumerable, but ICollection's GetMemebers does not + // return GetEnumerator. + // + // Not sure if this is the correct way to fix this, but it + // seems to work. Thanks to Bruce Dodson for the fix. + + Type[] inheritedInterfaces = type.GetInterfaces(); + + for (i = 0; i < inheritedInterfaces.Length; ++i) { - // Interface inheritance seems to be a different animal: - // more contractual, less structural. Thus, a Type that - // represents an interface that inherits from another - // interface does not return the inherited interface's - // methods in GetMembers. For example ICollection inherits - // from IEnumerable, but ICollection's GetMemebers does not - // return GetEnumerator. - // - // Not sure if this is the correct way to fix this, but it - // seems to work. Thanks to Bruce Dodson for the fix. - - Type[] inheritedInterfaces = type.GetInterfaces(); - - for (i = 0; i < inheritedInterfaces.Length; ++i) + Type inheritedType = inheritedInterfaces[i]; + MemberInfo[] imembers = inheritedType.GetMembers(flags); + for (n = 0; n < imembers.Length; n++) { - Type inheritedType = inheritedInterfaces[i]; - MemberInfo[] imembers = inheritedType.GetMembers(flags); - for (n = 0; n < imembers.Length; n++) + m = imembers[n]; + if (local[m.Name] == null) { - m = imembers[n]; - if (local[m.Name] == null) - { - items.Add(m); - } + items.Add(m); } } } diff --git a/src/testing/interfacetest.cs b/src/testing/interfacetest.cs index 2c24596bc..a52d30021 100644 --- a/src/testing/interfacetest.cs +++ b/src/testing/interfacetest.cs @@ -22,7 +22,16 @@ public interface ISayHello2 string SayHello(); } - public class InterfaceTest : ISayHello1, ISayHello2 + public interface IInterfaceResolutionTest + { + string TestMethod1(); + string TestMethod2(); + + string TestProperty1 { get; } + string TestProperty2 { get; } + } + + public class InterfaceTest : ISayHello1, ISayHello2, IInterfaceResolutionTest { public InterfaceTest() { @@ -43,6 +52,20 @@ string ISayHello2.SayHello() return "hello 2"; } + public string TestMethod1() + { + return "TestMethod1"; + } + + string IInterfaceResolutionTest.TestMethod2() + { + return "TestMethod2"; + } + + public string TestProperty1 => "TestProperty1"; + + string IInterfaceResolutionTest.TestProperty2 => "TestProperty2"; + public interface IPublic { } diff --git a/src/tests/test_interface.py b/src/tests/test_interface.py index 6b72c1a12..73892093b 100644 --- a/src/tests/test_interface.py +++ b/src/tests/test_interface.py @@ -67,3 +67,19 @@ def test_explicit_cast_to_interface(): assert i2.SayHello() == 'hello 2' assert hasattr(i2, 'SayHello') assert not hasattr(i2, 'HelloProperty') + + +def test_interface_method_and_property_lookup(): + """Test methods and properties in interfaces can be accessed""" + from Python.Test import InterfaceTest + + ob = InterfaceTest() + assert hasattr(ob, 'TestMethod1') + assert ob.TestMethod1() == 'TestMethod1' + assert hasattr(ob, 'TestMethod2') + assert ob.TestMethod2() == 'TestMethod2' + assert hasattr(ob, 'TestProperty1') + assert ob.TestProperty1 == 'TestProperty1' + assert hasattr(ob, 'TestProperty2') + assert ob.TestProperty2 == 'TestProperty2' +
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: