diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bdf5e32b..d27c136a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ details about the cause of the failure - Fix non-delegate types incorrectly appearing as callable. - Indexers can now be used with interface objects - Fixed a bug where indexers could not be used if they were inherited +- Made it possible to use `__len__` also on `ICollection<>` interface objects ## [2.5.0][] - 2020-06-14 diff --git a/src/runtime/slots/mp_length.cs b/src/runtime/slots/mp_length.cs index 42448a2e9..a13c7b6f8 100644 --- a/src/runtime/slots/mp_length.cs +++ b/src/runtime/slots/mp_length.cs @@ -26,7 +26,7 @@ public static MethodInfo Method } } - public static bool CanAssgin(Type clrType) + public static bool CanAssign(Type clrType) { if (typeof(ICollection).IsAssignableFrom(clrType)) { @@ -36,6 +36,10 @@ public static bool CanAssgin(Type clrType) { return true; } + if (clrType.IsInterface && clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(ICollection<>)) + { + return true; + } return false; } diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index c00247ca4..78c34a027 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -225,7 +225,7 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType) InitializeSlots(type, impl.GetType(), slotsHolder); if (Marshal.ReadIntPtr(type, TypeOffset.mp_length) == IntPtr.Zero - && mp_length_slot.CanAssgin(clrType)) + && mp_length_slot.CanAssign(clrType)) { InitializeSlot(type, TypeOffset.mp_length, mp_length_slot.Method, slotsHolder); } diff --git a/src/tests/test_mp_length.py b/src/tests/test_mp_length.py index c96ac77d1..e86fff288 100644 --- a/src/tests/test_mp_length.py +++ b/src/tests/test_mp_length.py @@ -47,3 +47,17 @@ def test_custom_generic_collection_explicit___len__(): s.Add(1) s.Add(10) assert len(s) == 2 + +def test_len_through_interface_generic(): + """Test __len__ for ICollection""" + import System.Collections.Generic + l = System.Collections.Generic.List[int]() + coll = System.Collections.Generic.ICollection[int](l) + assert len(coll) == 0 + +def test_len_through_interface(): + """Test __len__ for ICollection""" + import System.Collections + l = System.Collections.ArrayList() + coll = System.Collections.ICollection(l) + assert len(coll) == 0