Skip to content

Commit 6d59aea

Browse files
danabrlostmsu
authored andcommitted
Return interface objects when iterating over interface collections
1 parent 7f4f77b commit 6d59aea

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/runtime/classbase.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections;
3+
using System.Collections.Generic;
34
using System.Diagnostics;
45
using System.Runtime.InteropServices;
56
using System.Runtime.Serialization;
@@ -184,7 +185,6 @@ public static IntPtr tp_iter(IntPtr ob)
184185

185186
var e = co.inst as IEnumerable;
186187
IEnumerator o;
187-
188188
if (e != null)
189189
{
190190
o = e.GetEnumerator();
@@ -199,7 +199,22 @@ public static IntPtr tp_iter(IntPtr ob)
199199
}
200200
}
201201

202-
return new Iterator(o).pyHandle;
202+
var elemType = typeof(object);
203+
var iterType = co.inst.GetType();
204+
foreach(var ifc in iterType.GetInterfaces())
205+
{
206+
if (ifc.IsGenericType)
207+
{
208+
var genTypeDef = ifc.GetGenericTypeDefinition();
209+
if (genTypeDef == typeof(IEnumerable<>) || genTypeDef == typeof(IEnumerator<>))
210+
{
211+
elemType = ifc.GetGenericArguments()[0];
212+
break;
213+
}
214+
}
215+
}
216+
217+
return new Iterator(o, elemType).pyHandle;
203218
}
204219

205220

src/runtime/iterator.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ namespace Python.Runtime
1010
internal class Iterator : ExtensionType
1111
{
1212
private IEnumerator iter;
13+
private Type elemType;
1314

14-
public Iterator(IEnumerator e)
15+
public Iterator(IEnumerator e, Type elemType)
1516
{
1617
iter = e;
18+
this.elemType = elemType;
1719
}
1820

1921

@@ -41,7 +43,7 @@ public static IntPtr tp_iternext(IntPtr ob)
4143
return IntPtr.Zero;
4244
}
4345
object item = self.iter.Current;
44-
return Converter.ToPythonImplicit(item);
46+
return Converter.ToPython(item, self.elemType);
4547
}
4648

4749
public static IntPtr tp_iter(IntPtr ob)

src/tests/test_interface.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,19 @@ def test_implementation_access():
120120
assert 100 == i.__implementation__
121121
assert clrVal == i.__raw_implementation__
122122
assert i.__implementation__ != i.__raw_implementation__
123+
124+
125+
def test_interface_collection_iteration():
126+
"""Test interface type is used when iterating over interface collection"""
127+
import System
128+
from System.Collections.Generic import List
129+
elem = System.IComparable(System.Int32(100))
130+
typed_list = List[System.IComparable]()
131+
typed_list.Add(elem)
132+
for e in typed_list:
133+
assert type(e).__name__ == "IComparable"
134+
135+
untyped_list = System.Collections.ArrayList()
136+
untyped_list.Add(elem)
137+
for e in untyped_list:
138+
assert type(e).__name__ == "int"

0 commit comments

Comments
 (0)