@@ -390,6 +390,12 @@ internal static IntPtr ToPythonImplicit(object value)
390390 }
391391
392392
393+ internal static bool ToManaged ( IntPtr value , Type type ,
394+ out object result , bool setError )
395+ {
396+ var usedImplicit = false ;
397+ return ToManaged ( value , type , out result , setError , out usedImplicit ) ;
398+ }
393399 /// <summary>
394400 /// Return a managed object for the given Python object, taking funny
395401 /// byref types into account.
@@ -400,21 +406,26 @@ internal static IntPtr ToPythonImplicit(object value)
400406 /// <param name="setError">If true, call <c>Exceptions.SetError</c> with the reason for failure.</param>
401407 /// <returns>True on success</returns>
402408 internal static bool ToManaged ( IntPtr value , Type type ,
403- out object result , bool setError )
409+ out object result , bool setError , out bool usedImplicit )
404410 {
405411 if ( type . IsByRef )
406412 {
407413 type = type . GetElementType ( ) ;
408414 }
409- return Converter . ToManagedValue ( value , type , out result , setError ) ;
415+ return Converter . ToManagedValue ( value , type , out result , setError , out usedImplicit ) ;
410416 }
411417
412418 internal static bool ToManagedValue ( BorrowedReference value , Type obType ,
413419 out object result , bool setError )
414- => ToManagedValue ( value . DangerousGetAddress ( ) , obType , out result , setError ) ;
420+ {
421+ var usedImplicit = false ;
422+ return ToManagedValue ( value . DangerousGetAddress ( ) , obType , out result , setError , out usedImplicit ) ;
423+ }
424+
415425 internal static bool ToManagedValue ( IntPtr value , Type obType ,
416- out object result , bool setError )
426+ out object result , bool setError , out bool usedImplicit )
417427 {
428+ usedImplicit = false ;
418429 if ( obType == typeof ( PyObject ) )
419430 {
420431 Runtime . XIncref ( value ) ; // PyObject() assumes ownership
@@ -446,6 +457,18 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
446457 result = tmp ;
447458 return true ;
448459 }
460+ else
461+ {
462+ var type = tmp . GetType ( ) ;
463+ // check implicit conversions that receive tmp type and return obType
464+ var conversionMethod = type . GetMethod ( "op_Implicit" , new [ ] { type } ) ;
465+ if ( conversionMethod != null && conversionMethod . ReturnType == obType )
466+ {
467+ result = conversionMethod . Invoke ( null , new [ ] { tmp } ) ;
468+ usedImplicit = true ;
469+ return true ;
470+ }
471+ }
449472 if ( setError )
450473 {
451474 string typeString = tmp is null ? "null" : tmp . GetType ( ) . ToString ( ) ;
@@ -599,7 +622,7 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
599622 var underlyingType = Nullable . GetUnderlyingType ( obType ) ;
600623 if ( underlyingType != null )
601624 {
602- return ToManagedValue ( value , underlyingType , out result , setError ) ;
625+ return ToManagedValue ( value , underlyingType , out result , setError , out usedImplicit ) ;
603626 }
604627
605628 TypeCode typeCode = Type . GetTypeCode ( obType ) ;
@@ -612,6 +635,20 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
612635 }
613636 }
614637
638+ var opImplicit = obType . GetMethod ( "op_Implicit" , new [ ] { obType } ) ;
639+ if ( opImplicit != null )
640+ {
641+ if ( ToManagedValue ( value , opImplicit . ReturnType , out result , setError , out usedImplicit ) )
642+ {
643+ opImplicit = obType . GetMethod ( "op_Implicit" , new [ ] { result . GetType ( ) } ) ;
644+ if ( opImplicit != null )
645+ {
646+ result = opImplicit . Invoke ( null , new [ ] { result } ) ;
647+ }
648+ return opImplicit != null ;
649+ }
650+ }
651+
615652 return ToPrimitive ( value , obType , out result , setError ) ;
616653 }
617654
@@ -1046,12 +1083,12 @@ private static IList MakeList(IntPtr value, IntPtr IterObject, Type obType, Type
10461083 }
10471084
10481085 IntPtr item ;
1049-
1086+ var usedImplicit = false ;
10501087 while ( ( item = Runtime . PyIter_Next ( IterObject ) ) != IntPtr . Zero )
10511088 {
10521089 object obj ;
10531090
1054- if ( ! Converter . ToManaged ( item , elementType , out obj , setError ) )
1091+ if ( ! Converter . ToManaged ( item , elementType , out obj , setError , out usedImplicit ) )
10551092 {
10561093 Runtime . XDecref ( item ) ;
10571094 return null ;
0 commit comments