/// <summary> /// GetIterator Method /// </summary> /// /// <remarks> /// Return a new (Python) iterator for the object. This is equivalent /// to the Python expression "iter(object)". A PythonException will be /// raised if the object cannot be iterated. /// </remarks> public PyObject GetIterator() { IntPtr r = Runtime.PyObject_GetIter(obj); if (r == IntPtr.Zero) { throw new PythonException(); } return(new PyObject(r)); }
/// <summary> /// PyIter factory function. /// </summary> /// <remarks> /// Create a new PyIter from a given iterable. Like doing "iter(iterable)" in python. /// </remarks> /// <param name="iterable"></param> /// <returns></returns> public static PyIter GetIter(PyObject iterable) { if (iterable == null) { throw new ArgumentNullException(); } IntPtr val = Runtime.PyObject_GetIter(iterable.obj); PythonException.ThrowIfIsNull(val); return(new PyIter(val)); }
/// <summary> /// Convert a Python value to a correctly typed managed array instance. /// The Python value must support the Python iterator protocol or and the /// items in the sequence must be convertible to the target array type. /// </summary> private static bool ToArray(IntPtr value, Type obType, out object result, bool setError) { Type elementType = obType.GetElementType(); result = null; bool IsSeqObj = Runtime.PySequence_Check(value); var len = IsSeqObj ? Runtime.PySequence_Size(value) : -1; IntPtr IterObject = Runtime.PyObject_GetIter(value); if (IterObject == IntPtr.Zero) { if (setError) { SetConversionError(value, obType); } return(false); } Array items; var listType = typeof(List <>); var constructedListType = listType.MakeGenericType(elementType); IList list = IsSeqObj ? (IList)Activator.CreateInstance(constructedListType, new Object[] { (int)len }) : (IList)Activator.CreateInstance(constructedListType); IntPtr item; while ((item = Runtime.PyIter_Next(IterObject)) != IntPtr.Zero) { object obj = null; if (!Converter.ToManaged(item, elementType, out obj, true)) { Runtime.XDecref(item); return(false); } list.Add(obj); Runtime.XDecref(item); } Runtime.XDecref(IterObject); items = Array.CreateInstance(elementType, list.Count); list.CopyTo(items, 0); result = items; return(true); }
/// <summary> /// Convert a Python value to a correctly typed managed array instance. /// The Python value must support the Python iterator protocol or and the /// items in the sequence must be convertible to the target array type. /// </summary> private static bool ToArray(IntPtr value, Type obType, out object result, bool setError) { Type elementType = obType.GetElementType(); result = null; IntPtr IterObject = Runtime.PyObject_GetIter(value); if (IterObject == IntPtr.Zero || elementType.IsGenericType) { if (setError) { SetConversionError(value, obType); } else { // PyObject_GetIter will have set an error Exceptions.Clear(); } return(false); } var list = MakeList(value, IterObject, obType, elementType, setError); if (list == null) { return(false); } Array items = Array.CreateInstance(elementType, list.Count); list.CopyTo(items, 0); result = items; return(true); }
/// <summary> /// Convert a Python value to a correctly typed managed array instance. /// The Python value must support the Python iterator protocol or and the /// items in the sequence must be convertible to the target array type. /// </summary> private static bool ToArray(BorrowedReference value, Type obType, out object?result, bool setError) { Type elementType = obType.GetElementType(); result = null; using var IterObject = Runtime.PyObject_GetIter(value); if (IterObject.IsNull()) { if (setError) { SetConversionError(value, obType); } else { // PyObject_GetIter will have set an error Exceptions.Clear(); } return(false); } IList list; try { // MakeGenericType can throw because elementType may not be a valid generic argument even though elementType[] is a valid array type. // For example, if elementType is a pointer type. // See https://docs.microsoft.com/en-us/dotnet/api/system.type.makegenerictype#System_Type_MakeGenericType_System_Type var constructedListType = typeof(List <>).MakeGenericType(elementType); bool IsSeqObj = Runtime.PySequence_Check(value); object[] constructorArgs = Array.Empty <object>(); if (IsSeqObj) { var len = Runtime.PySequence_Size(value); if (len >= 0) { if (len <= int.MaxValue) { constructorArgs = new object[] { (int)len }; } } else { // for the sequences, that explicitly deny calling __len__() Exceptions.Clear(); } } // CreateInstance can throw even if MakeGenericType succeeded. // See https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance#System_Activator_CreateInstance_System_Type_ list = (IList)Activator.CreateInstance(constructedListType, args: constructorArgs); } catch (Exception e) { if (setError) { Exceptions.SetError(e); SetConversionError(value, obType); } return(false); } while (true) { using var item = Runtime.PyIter_Next(IterObject.Borrow()); if (item.IsNull()) { break; } if (!Converter.ToManaged(item.Borrow(), elementType, out var obj, setError)) { return(false); } list.Add(obj); } if (Exceptions.ErrorOccurred()) { if (!setError) { Exceptions.Clear(); } return(false); } Array items = Array.CreateInstance(elementType, list.Count); list.CopyTo(items, 0); result = items; return(true); }
/// <summary> /// Convert a Python value to a correctly typed managed array instance. /// The Python value must support the Python iterator protocol or and the /// items in the sequence must be convertible to the target array type. /// </summary> private static bool ToArray(IntPtr value, Type obType, out object result, bool setError) { Type elementType = obType.GetElementType(); result = null; IntPtr IterObject = Runtime.PyObject_GetIter(value); if (IterObject == IntPtr.Zero) { if (setError) { SetConversionError(value, obType); } else { // PyObject_GetIter will have set an error Exceptions.Clear(); } return(false); } IList list; try { // MakeGenericType can throw because elementType may not be a valid generic argument even though elementType[] is a valid array type. // For example, if elementType is a pointer type. // See https://docs.microsoft.com/en-us/dotnet/api/system.type.makegenerictype#System_Type_MakeGenericType_System_Type var constructedListType = typeof(List <>).MakeGenericType(elementType); bool IsSeqObj = Runtime.PySequence_Check(value); if (IsSeqObj) { var len = Runtime.PySequence_Size(value); list = (IList)Activator.CreateInstance(constructedListType, new Object[] { (int)len }); } else { // CreateInstance can throw even if MakeGenericType succeeded. // See https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance#System_Activator_CreateInstance_System_Type_ list = (IList)Activator.CreateInstance(constructedListType); } } catch (Exception e) { if (setError) { Exceptions.SetError(e); SetConversionError(value, obType); } return(false); } IntPtr item; while ((item = Runtime.PyIter_Next(IterObject)) != IntPtr.Zero) { object obj; if (!Converter.ToManaged(item, elementType, out obj, setError)) { Runtime.XDecref(item); return(false); } list.Add(obj); Runtime.XDecref(item); } Runtime.XDecref(IterObject); Array items = Array.CreateInstance(elementType, list.Count); list.CopyTo(items, 0); result = items; return(true); }