| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Reflection; | ||
|
|
||
| namespace Python.Runtime.Slots | ||
| { | ||
| internal static class mp_length_slot | ||
| { | ||
| /// <summary> | ||
| /// Implements __len__ for classes that implement ICollection | ||
| /// (this includes any IList implementer or Array subclass) | ||
| /// </summary> | ||
| public static int mp_length(IntPtr ob) | ||
| { | ||
| var co = ManagedType.GetManagedObject(ob) as CLRObject; | ||
| if (co == null) | ||
| { | ||
| Exceptions.RaiseTypeError("invalid object"); | ||
| } | ||
|
|
||
| // first look for ICollection implementation directly | ||
| if (co.inst is ICollection c) | ||
| { | ||
| return c.Count; | ||
| } | ||
|
|
||
| Type clrType = co.inst.GetType(); | ||
|
|
||
| // now look for things that implement ICollection<T> directly (non-explicitly) | ||
| PropertyInfo p = clrType.GetProperty("Count"); | ||
| if (p != null && clrType.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>))) | ||
| { | ||
| return (int)p.GetValue(co.inst, null); | ||
| } | ||
|
|
||
| // finally look for things that implement the interface explicitly | ||
| var iface = clrType.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>)); | ||
| if (iface != null) | ||
| { | ||
| p = iface.GetProperty(nameof(ICollection<int>.Count)); | ||
| return (int)p.GetValue(co.inst, null); | ||
| } | ||
|
|
||
| Exceptions.SetError(Exceptions.TypeError, $"object of type '{clrType.Name}' has no len()"); | ||
| return -1; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace Python.Test | ||
| { | ||
| public class MpLengthCollectionTest : ICollection | ||
| { | ||
| private readonly List<int> items; | ||
|
|
||
| public MpLengthCollectionTest() | ||
| { | ||
| SyncRoot = new object(); | ||
| items = new List<int> | ||
| { | ||
| 1, | ||
| 2, | ||
| 3 | ||
| }; | ||
| } | ||
|
|
||
| public int Count => items.Count; | ||
|
|
||
| public object SyncRoot { get; private set; } | ||
|
|
||
| public bool IsSynchronized => false; | ||
|
|
||
| public void CopyTo(Array array, int index) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| public IEnumerator GetEnumerator() | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
| } | ||
|
|
||
| public class MpLengthExplicitCollectionTest : ICollection | ||
| { | ||
| private readonly List<int> items; | ||
| private readonly object syncRoot; | ||
|
|
||
| public MpLengthExplicitCollectionTest() | ||
| { | ||
| syncRoot = new object(); | ||
| items = new List<int> | ||
| { | ||
| 9, | ||
| 10 | ||
| }; | ||
| } | ||
| int ICollection.Count => items.Count; | ||
|
|
||
| object ICollection.SyncRoot => syncRoot; | ||
|
|
||
| bool ICollection.IsSynchronized => false; | ||
|
|
||
| void ICollection.CopyTo(Array array, int index) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| IEnumerator IEnumerable.GetEnumerator() | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
| } | ||
|
|
||
| public class MpLengthGenericCollectionTest<T> : ICollection<T> | ||
| { | ||
| private readonly List<T> items; | ||
|
|
||
| public MpLengthGenericCollectionTest() { | ||
| SyncRoot = new object(); | ||
| items = new List<T>(); | ||
| } | ||
|
|
||
| public int Count => items.Count; | ||
|
|
||
| public object SyncRoot { get; private set; } | ||
|
|
||
| public bool IsSynchronized => false; | ||
|
|
||
| public bool IsReadOnly => false; | ||
|
|
||
| public void Add(T item) | ||
| { | ||
| items.Add(item); | ||
| } | ||
|
|
||
| public void Clear() | ||
| { | ||
| items.Clear(); | ||
| } | ||
|
|
||
| public bool Contains(T item) | ||
| { | ||
| return items.Contains(item); | ||
| } | ||
|
|
||
| public void CopyTo(T[] array, int arrayIndex) | ||
| { | ||
| items.CopyTo(array, arrayIndex); | ||
| } | ||
|
|
||
| public IEnumerator GetEnumerator() | ||
| { | ||
| return ((IEnumerable)items).GetEnumerator(); | ||
| } | ||
|
|
||
| public bool Remove(T item) | ||
| { | ||
| return items.Remove(item); | ||
| } | ||
|
|
||
| IEnumerator<T> IEnumerable<T>.GetEnumerator() | ||
| { | ||
| return items.GetEnumerator(); | ||
| } | ||
| } | ||
|
|
||
| public class MpLengthExplicitGenericCollectionTest<T> : ICollection<T> | ||
| { | ||
| private readonly List<T> items; | ||
|
|
||
| public MpLengthExplicitGenericCollectionTest() | ||
| { | ||
| items = new List<T>(); | ||
| } | ||
|
|
||
| int ICollection<T>.Count => items.Count; | ||
|
|
||
| bool ICollection<T>.IsReadOnly => false; | ||
|
|
||
| public void Add(T item) | ||
| { | ||
| items.Add(item); | ||
| } | ||
|
|
||
| void ICollection<T>.Clear() | ||
| { | ||
| items.Clear(); | ||
| } | ||
|
|
||
| bool ICollection<T>.Contains(T item) | ||
| { | ||
| return items.Contains(item); | ||
| } | ||
|
|
||
| void ICollection<T>.CopyTo(T[] array, int arrayIndex) | ||
| { | ||
| items.CopyTo(array, arrayIndex); | ||
| } | ||
|
|
||
| IEnumerator<T> IEnumerable<T>.GetEnumerator() | ||
| { | ||
| return items.GetEnumerator(); | ||
| } | ||
|
|
||
| IEnumerator IEnumerable.GetEnumerator() | ||
| { | ||
| return ((IEnumerable)items).GetEnumerator(); | ||
| } | ||
|
|
||
| bool ICollection<T>.Remove(T item) | ||
| { | ||
| return items.Remove(item); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # -*- coding: utf-8 -*- | ||
|
|
||
| """Test __len__ for .NET classes implementing ICollection/ICollection<T>.""" | ||
|
|
||
| import System | ||
| import pytest | ||
| from Python.Test import MpLengthCollectionTest, MpLengthExplicitCollectionTest, MpLengthGenericCollectionTest, MpLengthExplicitGenericCollectionTest | ||
|
|
||
| def test_simple___len__(): | ||
| """Test __len__ for simple ICollection implementers""" | ||
| import System | ||
| import System.Collections.Generic | ||
| l = System.Collections.Generic.List[int]() | ||
| assert len(l) == 0 | ||
| l.Add(5) | ||
| l.Add(6) | ||
| assert len(l) == 2 | ||
|
|
||
| d = System.Collections.Generic.Dictionary[int, int]() | ||
| assert len(d) == 0 | ||
| d.Add(4, 5) | ||
| assert len(d) == 1 | ||
|
|
||
| a = System.Array[int]([0,1,2,3]) | ||
| assert len(a) == 4 | ||
|
|
||
| def test_custom_collection___len__(): | ||
| """Test __len__ for custom collection class""" | ||
| s = MpLengthCollectionTest() | ||
| assert len(s) == 3 | ||
|
|
||
| def test_custom_collection_explicit___len__(): | ||
| """Test __len__ for custom collection class that explicitly implements ICollection""" | ||
| s = MpLengthExplicitCollectionTest() | ||
| assert len(s) == 2 | ||
|
|
||
| def test_custom_generic_collection___len__(): | ||
| """Test __len__ for custom generic collection class""" | ||
| s = MpLengthGenericCollectionTest[int]() | ||
| s.Add(1) | ||
| s.Add(2) | ||
| assert len(s) == 2 | ||
|
|
||
| def test_custom_generic_collection_explicit___len__(): | ||
| """Test __len__ for custom generic collection that explicity implements ICollection<T>""" | ||
| s = MpLengthExplicitGenericCollectionTest[int]() | ||
| s.Add(1) | ||
| s.Add(10) | ||
| assert len(s) == 2 |
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityToo many reflections every times, you can try like this.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI agree, but I feel like it would be good to have feature + tests first. It can be optimized later.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.