@@ -303,6 +303,11 @@ internal static IntPtr ToPythonImplicit(object value)
303
303
/// Return a managed object for the given Python object, taking funny
304
304
/// byref types into account.
305
305
/// </summary>
306
+ /// <param name="value">A Python object</param>
307
+ /// <param name="type">The desired managed type</param>
308
+ /// <param name="result">Receives the managed object</param>
309
+ /// <param name="setError">If true, call <c>Exceptions.SetError</c> with the reason for failure.</param>
310
+ /// <returns>True on success</returns>
306
311
internal static bool ToManaged ( IntPtr value , Type type ,
307
312
out object result , bool setError )
308
313
{
@@ -341,7 +346,10 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
341
346
result = tmp ;
342
347
return true ;
343
348
}
344
- Exceptions . SetError ( Exceptions . TypeError , $ "value cannot be converted to { obType } ") ;
349
+ if ( setError )
350
+ {
351
+ Exceptions . SetError ( Exceptions . TypeError , $ "value cannot be converted to { obType } ") ;
352
+ }
345
353
return false ;
346
354
}
347
355
if ( mt is ClassBase )
@@ -376,6 +384,15 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
376
384
obType = obType . GetGenericArguments ( ) [ 0 ] ;
377
385
}
378
386
387
+ if ( obType . ContainsGenericParameters )
388
+ {
389
+ if ( setError )
390
+ {
391
+ Exceptions . SetError ( Exceptions . TypeError , $ "Cannot create an instance of the open generic type { obType } ") ;
392
+ }
393
+ return false ;
394
+ }
395
+
379
396
if ( obType . IsArray )
380
397
{
381
398
return ToArray ( value , obType , out result , setError ) ;
@@ -777,7 +794,7 @@ private static void SetConversionError(IntPtr value, Type target)
777
794
IntPtr ob = Runtime . PyObject_Repr ( value ) ;
778
795
string src = Runtime . GetManagedString ( ob ) ;
779
796
Runtime . XDecref ( ob ) ;
780
- Exceptions . SetError ( Exceptions . TypeError , $ "Cannot convert { src } to { target } ") ;
797
+ Exceptions . RaiseTypeError ( $ "Cannot convert { src } to { target } ") ;
781
798
}
782
799
783
800
@@ -791,32 +808,58 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s
791
808
Type elementType = obType . GetElementType ( ) ;
792
809
result = null ;
793
810
794
- bool IsSeqObj = Runtime . PySequence_Check ( value ) ;
795
- var len = IsSeqObj ? Runtime . PySequence_Size ( value ) : - 1 ;
796
-
797
811
IntPtr IterObject = Runtime . PyObject_GetIter ( value ) ;
798
-
799
- if ( IterObject == IntPtr . Zero ) {
812
+ if ( IterObject == IntPtr . Zero )
813
+ {
800
814
if ( setError )
801
815
{
802
816
SetConversionError ( value , obType ) ;
803
817
}
818
+ else
819
+ {
820
+ // PyObject_GetIter will have set an error
821
+ Exceptions . Clear ( ) ;
822
+ }
804
823
return false ;
805
824
}
806
825
807
- Array items ;
826
+ IList list ;
827
+ try
828
+ {
829
+ // MakeGenericType can throw because elementType may not be a valid generic argument even though elementType[] is a valid array type.
830
+ // For example, if elementType is a pointer type.
831
+ // See https://docs.microsoft.com/en-us/dotnet/api/system.type.makegenerictype#System_Type_MakeGenericType_System_Type
832
+ var constructedListType = typeof ( List < > ) . MakeGenericType ( elementType ) ;
833
+ bool IsSeqObj = Runtime . PySequence_Check ( value ) ;
834
+ if ( IsSeqObj )
835
+ {
836
+ var len = Runtime . PySequence_Size ( value ) ;
837
+ list = ( IList ) Activator . CreateInstance ( constructedListType , new Object [ ] { ( int ) len } ) ;
838
+ }
839
+ else
840
+ {
841
+ // CreateInstance can throw even if MakeGenericType succeeded.
842
+ // See https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance#System_Activator_CreateInstance_System_Type_
843
+ list = ( IList ) Activator . CreateInstance ( constructedListType ) ;
844
+ }
845
+ }
846
+ catch ( Exception e )
847
+ {
848
+ if ( setError )
849
+ {
850
+ Exceptions . SetError ( e ) ;
851
+ SetConversionError ( value , obType ) ;
852
+ }
853
+ return false ;
854
+ }
808
855
809
- var listType = typeof ( List < > ) ;
810
- var constructedListType = listType . MakeGenericType ( elementType ) ;
811
- IList list = IsSeqObj ? ( IList ) Activator . CreateInstance ( constructedListType , new Object [ ] { ( int ) len } ) :
812
- ( IList ) Activator . CreateInstance ( constructedListType ) ;
813
856
IntPtr item ;
814
857
815
858
while ( ( item = Runtime . PyIter_Next ( IterObject ) ) != IntPtr . Zero )
816
859
{
817
- object obj = null ;
860
+ object obj ;
818
861
819
- if ( ! Converter . ToManaged ( item , elementType , out obj , true ) )
862
+ if ( ! Converter . ToManaged ( item , elementType , out obj , setError ) )
820
863
{
821
864
Runtime . XDecref ( item ) ;
822
865
return false ;
@@ -827,7 +870,7 @@ private static bool ToArray(IntPtr value, Type obType, out object result, bool s
827
870
}
828
871
Runtime . XDecref ( IterObject ) ;
829
872
830
- items = Array . CreateInstance ( elementType , list . Count ) ;
873
+ Array items = Array . CreateInstance ( elementType , list . Count ) ;
831
874
list . CopyTo ( items , 0 ) ;
832
875
833
876
result = items ;
0 commit comments