@@ -837,50 +837,53 @@ private static void SetConversionError(IntPtr value, Type target)
837837
838838 /// <summary>
839839 /// Convert a Python value to a correctly typed managed array instance.
840- /// The Python value must support the Python sequence protocol and the
840+ /// The Python value must support the Python iterator protocol or and the
841841 /// items in the sequence must be convertible to the target array type.
842842 /// </summary>
843843 private static bool ToArray ( IntPtr value , Type obType , out object result , bool setError )
844844 {
845845 Type elementType = obType . GetElementType ( ) ;
846- var size = Runtime . PySequence_Size ( value ) ;
847846 result = null ;
848847
849- if ( size < 0 )
850- {
848+ bool IsSeqObj = Runtime . PySequence_Check ( value ) ;
849+ var len = IsSeqObj ? Runtime . PySequence_Size ( value ) : - 1 ;
850+
851+ IntPtr IterObject = Runtime . PyObject_GetIter ( value ) ;
852+
853+ if ( IterObject == IntPtr . Zero ) {
851854 if ( setError )
852855 {
853856 SetConversionError ( value , obType ) ;
854857 }
855858 return false ;
856859 }
857860
858- Array items = Array . CreateInstance ( elementType , size ) ;
861+ Array items ;
862+
863+ var listType = typeof ( List < > ) ;
864+ var constructedListType = listType . MakeGenericType ( elementType ) ;
865+ IList list = IsSeqObj ? ( IList ) Activator . CreateInstance ( constructedListType , new Object [ ] { ( int ) len } ) :
866+ ( IList ) Activator . CreateInstance ( constructedListType ) ;
867+ IntPtr item ;
859868
860- // XXX - is there a better way to unwrap this if it is a real array?
861- for ( var i = 0 ; i < size ; i ++ )
869+ while ( ( item = Runtime . PyIter_Next ( IterObject ) ) != IntPtr . Zero )
862870 {
863871 object obj = null ;
864- IntPtr item = Runtime . PySequence_GetItem ( value , i ) ;
865- if ( item == IntPtr . Zero )
866- {
867- if ( setError )
868- {
869- SetConversionError ( value , obType ) ;
870- return false ;
871- }
872- }
873872
874873 if ( ! Converter . ToManaged ( item , elementType , out obj , true ) )
875874 {
876875 Runtime . XDecref ( item ) ;
877876 return false ;
878877 }
879878
880- items . SetValue ( obj , i ) ;
879+ list . Add ( obj ) ;
881880 Runtime . XDecref ( item ) ;
882881 }
882+ Runtime . XDecref ( IterObject ) ;
883883
884+ items = Array . CreateInstance ( elementType , list . Count ) ;
885+ list . CopyTo ( items , 0 ) ;
886+
884887 result = items ;
885888 return true ;
886889 }
0 commit comments