8000 Implement List Conversion, Reflect PR #37 Tests · QuantConnect/pythonnet@19fc8c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 19fc8c8

Browse files
committed
Implement List Conversion, Reflect PR #37 Tests
1 parent 55d1b04 commit 19fc8c8

File tree

2 files changed

+75
-8
lines changed

2 files changed

+75
-8
lines changed

src/embed_tests/TestConverter.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,30 @@ public void Dispose()
3434
PythonEngine.Shutdown();
3535
}
3636

37+
[Test]
38+
public void ConvertListRoundTrip()
39+
{
40+
var list = new List<Type> { typeof(decimal), typeof(int) };
41+
var py = list.ToPython();
42+
object result;
43+
var converted = Converter.ToManaged(py.Handle, typeof(List<Type>), out result, false);
44+
45+
Assert.IsTrue(converted);
46+
Assert.AreEqual(result, list);
47+
}
48+
49+
[Test]
50+
public void ConvertPyListToArray()
51+
{
52+
var array = new List<Type> { typeof(decimal), typeof(int) };
53+
var py = array.ToPython();
54+
object result;
55+
var converted = Converter.ToManaged(py.Handle, typeof(Type[]), out result, false);
56+
57+
Assert.IsTrue(converted);
58+
Assert.AreEqual(result, array);
59+
}
60+
3761
[Test]
3862
public void TestConvertSingleToManaged(
3963
[Values(float.PositiveInfinity, float.NegativeInfinity, float.MinValue, float.MaxValue, float.NaN,

src/runtime/converter.cs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,15 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
416416
return true;
417417
}
418418

419+
if (obType.IsGenericType && Runtime.PyObject_TYPE(value) == Runtime.PyListType)
420+
{
421+
var typeDefinition = obType.GetGenericTypeDefinition();
422+
if (typeDefinition == typeof(List<>))
423+
{
424+
return ToList(value, obType, out result, setError);
425+
}
426+
}
427+
419428
// Common case: if the Python value is a wrapped managed object
420429
// instance, just return the wrapped object.
421430
ManagedType mt = ManagedType.GetManagedObject(value);
@@ -948,7 +957,7 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s
948957
result = null;
949958

950959
IntPtr IterObject = Runtime.PyObject_GetIter(value);
951-
if (IterObject == IntPtr.Zero)
960+
if (IterObject == IntPtr.Zero || elementType.IsGenericType)
952961
{
953962
if (setError)
954963
{
@@ -962,6 +971,43 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s
962971
return false;
963972
}
964973

974+
var list = MakeList(value, IterObject, obType, elementType, setError);
975+
if (list == null)
976+
{
977+
return false;
978+
}
979+
980+
Array items = Array.CreateInstance(elementType, list.Count);
981+
list.CopyTo(items, 0);
982+
983+
result = items;
984+
return true;
985+
}
986+
987+
/// <summary>
988+
/// Convert a Python value to a correctly typed managed list instance.
989+
/// The Python value must support the Python sequence protocol and the
990+
/// items in the sequence must be convertible to the target list type.
991+
/// </summary>
992+
private static bool ToList(IntPtr value, Type obType, out object result, bool setError)
993+
{
994+
var elementType = obType.GetGenericArguments()[0];
995+
IntPtr IterObject = Runtime.PyObject_GetIter(value);
996+
result = MakeList(value, IterObject, obType, elementType, setError);
997+
return result != null;
998+
}
999+
1000+
/// <summary>
1001+
/// Helper function for ToArray and ToList that creates a IList out of iterable objects
1002+
/// </summary>
1003+
/// <param name="value"></param>
1004+
/// <param name="IterObject"></param>
1005+
/// <param name="obType"></param>
1006+
/// <param name="elementType"></param>
1007+
/// <param name="setError"></param>
1008+
/// <returns></returns>
1009+
private static IList MakeList(IntPtr value, IntPtr IterObject, Type obType, Type elementType, bool setError)
1010+
{
9651011
IList list;
9661012
try
9671013
{
@@ -989,7 +1035,8 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s
9891035
Exceptions.SetError(e);
9901036
SetConversionError(value, obType);
9911037
}
992-
return false;
1038+
1039+
return null;
9931040
}
9941041

9951042
IntPtr item;
@@ -1001,19 +1048,15 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s
10011048
if (!Converter.ToManaged(item, elementType, out obj, setError))
10021049
{
10031050
Runtime.XDecref(item);
1004-
return false;
1051+
return null;
10051052
}
10061053

10071054
list.Add(obj);
10081055
Runtime.XDecref(item);
10091056
}
10101057
Runtime.XDecref(IterObject);
10111058

1012-
Array items = Array.CreateInstance(elementType, list.Count);
1013-
list.CopyTo(items, 0);
1014-
1015-
result = items;
1016-
return true;
1059+
return list;
10171060
}
10181061

10191062

0 commit comments

Comments
 (0)
0