8000 Merge branch 'master' into intern-string · pythonnet/pythonnet@021bf9f · GitHub
[go: up one dir, main page]

Skip to content

Commit 021bf9f

Browse files
committed
Merge branch 'master' into intern-string
2 parents c74afb0 + de7c7c2 commit 021bf9f

File tree

10 files changed

+71
-9
lines changed

10 files changed

+71
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ details about the cause of the failure
3131
- Fix non-delegate types incorrectly appearing as callable.
3232
- Indexers can now be used with interface objects
3333
- Fixed a bug where indexers could not be used if they were inherited
34+
- Made it possible to use `__len__` also on `ICollection<>` interface objects
3435

3536
## [2.5.0][] - 2020-06-14
3637

appveyor.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ environment:
1616

1717
matrix:
1818
- PYTHON_VERSION: 3.8
19+
BUILD_OPTS: --xplat
1920
- PYTHON_VERSION: 3.7
2021
BUILD_OPTS: --xplat
2122
- PYTHON_VERSION: 3.6
2223
BUILD_OPTS: --xplat
2324
- PYTHON_VERSION: 3.8
2425
- PYTHON_VERSION: 3.7
2526
- PYTHON_VERSION: 3.6
27+
- PYTHON_VERSION: 3.8
28+
PYTHONNET_SHUTDOWN_MODE: Soft
2629
- PYTHON_VERSION: 3.7
2730
PYTHONNET_SHUTDOWN_MODE: Soft
28-
- PYTHON_VERSION: 3.8
31+
- PYTHON_VERSION: 3.6
2932
PYTHONNET_SHUTDOWN_MODE: Soft
3033
init:
3134
# Update Environment Variables based on matrix/platform

src/runtime/Python.Runtime.15.csproj

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
<PackageLicenseUrl>https://github.com/pythonnet/pythonnet/blob/master/LICENSE</PackageLicenseUrl>
1919
<RepositoryUrl>https://github.com/pythonnet/pythonnet</RepositoryUrl>
2020
<RepositoryType>git</RepositoryType>
21+
<!-- The following is recommended for public projects -->
22+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
23+
<DebugSymbols>true</DebugSymbols>
24+
<IncludeSymbols>true</IncludeSymbols>
25+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
2126
<!--<PackageReleaseNotes>https://github.com/pythonnet/pythonnet/releases/tag/v2.4.0</PackageReleaseNotes>-->
2227
<PackageTags>python interop dynamic dlr Mono pinvoke</PackageTags>
2328
<PackageIconUrl>https://raw.githubusercontent.com/pythonnet/pythonnet/master/src/console/python-clear.ico</PackageIconUrl>
@@ -118,7 +123,7 @@
118123

119124
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
120125
<PackageReference Include="System.Security.Permissions" Version="4.4.0" />
121-
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
126+
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
122127
</ItemGroup>
123128

124129
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
@@ -134,6 +139,8 @@
134139
<PrivateAssets>all</PrivateAssets>
135140
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
136141
</PackageReference>
142+
<!-- The following is recommended for public projects -->
143+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
137144
</ItemGroup>
138145

139146
<ItemGroup>

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/runtime/polyfill/ReflectionPolifills.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public static AssemblyBuilder DefineDynamicAssembly(this AppDomain appDomain, As
1616

1717
public static Type CreateType(this TypeBuilder typeBuilder)
1818
{
19-
return typeBuilder.GetTypeInfo().GetType();
19+
return typeBuilder.CreateTypeInfo();
2020
}
2121
#endif
2222
public static T GetCustomAttribute<T>(this Type type) where T: Attribute

src/runtime/slots/mp_length.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static MethodInfo Method
2626
}
2727
}
2828

29-
public static bool CanAssgin(Type clrType)
29+
public static bool CanAssign(Type clrType)
3030
{
3131
if (typeof(ICollection).IsAssignableFrom(clrType))
3232
{
@@ -36,6 +36,10 @@ public static bool CanAssgin(Type clrType)
3636
{
3737
return true;
3838
}
39+
if (clrType.IsInterface && clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(ICollection<>))
40+
{
41+
return true;
42+
}
3943
return false;
4044
}
4145

src/runtime/typemanager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType)
225225
InitializeSlots(type, impl.GetType(), slotsHolder);
226226

227227
if (Marshal.ReadIntPtr(type, TypeOffset.mp_length) == IntPtr.Zero
228-
&& mp_length_slot.CanAssgin(clrType))
228+
&& mp_length_slot.CanAssign(clrType))
229229
{
230230
InitializeSlot(type, TypeOffset.mp_length, mp_length_slot.Method, slotsHolder);
231231
}

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"

src/tests/test_mp_length.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,17 @@ def test_custom_generic_collection_explicit___len__():
4747
s.Add(1)
4848
s.Add(10)
4949
assert len(s) == 2
50+
51+
def test_len_through_interface_generic():
52+
"""Test __len__ for ICollection<T>"""
53+
import System.Collections.Generic
54+
l = System.Collections.Generic.List[int]()
55+
coll = System.Collections.Generic.ICollection[int](l)
56+
assert len(coll) == 0
57+
58+
def test_len_through_interface():
59+
"""Test __len__ for ICollection"""
60+
import System.Collections
61+
l = System.Collections.ArrayList()
62+
coll = System.Collections.ICollection(l)
63+
assert len(coll) == 0

0 commit comments

Comments
 (0)
0