From 8df73d3f19a859d3c639e735aa73e81300645996 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 26 Sep 2019 23:52:36 +0200 Subject: [PATCH 1/4] Drop List and IEnumerable conversions --- src/runtime/converter.cs | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 5d8769a73..a53d3114c 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -135,22 +135,6 @@ internal static IntPtr ToPython(object value, Type type) return result; } - if (value is IList && !(value is INotifyPropertyChanged) && value.GetType().IsGenericType) - { - using (var resultlist = new PyList()) - { - foreach (object o in (IEnumerable)value) - { - using (var p = new PyObject(ToPython(o, o?.GetType()))) - { - resultlist.Append(p); - } - } - Runtime.XIncref(resultlist.Handle); - return resultlist.Handle; - } - } - // it the type is a python subclass of a managed type then return the // underlying python object rather than construct a new wrapper object. var pyderived = value as IPythonDerivedType; @@ -231,21 +215,6 @@ internal static IntPtr ToPython(object value, Type type) return Runtime.PyLong_FromUnsignedLongLong((ulong)value); default: - if (value is IEnumerable) - { - using (var resultlist = new PyList()) - { - foreach (object o in (IEnumerable)value) - { - using (var p = new PyObject(ToPython(o, o?.GetType()))) - { - resultlist.Append(p); - } - } - Runtime.XIncref(resultlist.Handle); - return resultlist.Handle; - } - } result = CLRObject.GetInstHandle(value, type); return result; } @@ -862,7 +831,7 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s var listType = typeof(List<>); var constructedListType = listType.MakeGenericType(elementType); - IList list = IsSeqObj ? (IList) Activator.CreateInstance(constructedListType, new Object[] {(int) len}) : + IList list = IsSeqObj ? (IList) Activator.CreateInstance(constructedListType, new Object[] {(int) len}) : (IList) Activator.CreateInstance(constructedListType); IntPtr item; @@ -883,7 +852,7 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s items = Array.CreateInstance(elementType, list.Count); list.CopyTo(items, 0); - + result = items; return true; } From ea8df83a54370f9144ede927675b6e3dadf02003 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 27 Sep 2019 08:00:36 +0200 Subject: [PATCH 2/4] Try to guess the correct element type from an enumerator, use in conversion --- src/runtime/converter.cs | 2 +- src/runtime/iterator.cs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index a53d3114c..789748436 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -155,7 +155,7 @@ internal static IntPtr ToPython(object value, Type type) // type is. we'd rather have the object bound to the actual // implementing class. - type = value.GetType(); + type = type ?? value.GetType(); TypeCode tc = Type.GetTypeCode(type); diff --git a/src/runtime/iterator.cs b/src/runtime/iterator.cs index f9cf10178..a42f5e3af 100644 --- a/src/runtime/iterator.cs +++ b/src/runtime/iterator.cs @@ -1,3 +1,4 @@ +using System.Linq; using System; using System.Collections; @@ -10,10 +11,18 @@ namespace Python.Runtime internal class Iterator : ExtensionType { private IEnumerator iter; + private Type type; public Iterator(IEnumerator e) { iter = e; + + var genericType = e.GetType().GetInterfaces().FirstOrDefault( + x => x.IsGenericType && + x.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IEnumerator<>) + ); + + type = genericType?.GetGenericArguments().FirstOrDefault(); } @@ -41,7 +50,7 @@ public static IntPtr tp_iternext(IntPtr ob) return IntPtr.Zero; } object item = self.iter.Current; - return Converter.ToPythonImplicit(item); + return Converter.ToPython(item, self.type); } public static IntPtr tp_iter(IntPtr ob) From 00e4030fbfd823f93dd692256e50f0dff198bb06 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 27 Sep 2019 08:44:45 +0200 Subject: [PATCH 3/4] Try hard not to convert everything to Object --- src/runtime/converter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 789748436..393bc98d5 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -155,7 +155,7 @@ internal static IntPtr ToPython(object value, Type type) // type is. we'd rather have the object bound to the actual // implementing class. - type = type ?? value.GetType(); + type = type == null || type == typeof(object) ? value.GetType() : type; TypeCode tc = Type.GetTypeCode(type); From cf18983991e44bccf3b79bcd58beea349e9e8562 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 27 Sep 2019 08:51:29 +0200 Subject: [PATCH 4/4] Revert "Try hard not to convert everything to Object" This reverts commit 00e4030fbfd823f93dd692256e50f0dff198bb06. --- src/runtime/converter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 393bc98d5..789748436 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -155,7 +155,7 @@ internal static IntPtr ToPython(object value, Type type) // type is. we'd rather have the object bound to the actual // implementing class. - type = type == null || type == typeof(object) ? value.GetType() : type; + type = type ?? value.GetType(); TypeCode tc = Type.GetTypeCode(type);