@@ -740,6 +740,164 @@ from Python.EmbeddingTest import *
740740" ) ) ;
741741 }
742742
743+ public class OverloadsTestClass
744+ {
745+
746+ public string Method1 ( string positionalArg , decimal namedArg1 = 1.2m , int namedArg2 = 123 )
747+ {
748+ Console . WriteLine ( "1" ) ;
749+ return "Method1 Overload 1" ;
750+ }
751+
752+ public string Method1 ( decimal namedArg1 = 1.2m , int namedArg2 = 123 )
753+ {
754+ Console . WriteLine ( "2" ) ;
755+ return "Method1 Overload 2" ;
756+ }
757+
758+ // ----
759+
760+ public string Method2 ( string arg1 , int arg2 , decimal arg3 , decimal kwarg1 = 1.1m , bool kwarg2 = false , string kwarg3 = "" )
761+ {
762+ return "Method2 Overload 1" ;
763+ }
764+
765+ public string Method2 ( string arg1 , int arg2 , decimal kwarg1 = 1.1m , bool kwarg2 = false , string kwarg3 = "" )
766+ {
767+ return "Method2 Overload 2" ;
768+ }
769+
770+ // ----
771+
772+ public string Method3 ( string arg1 , int arg2 , float arg3 , float kwarg1 = 1.1f , bool kwarg2 = false , string kwarg3 = "" )
773+ {
774+ return "Method3 Overload 1" ;
775+ }
776+
777+ public string Method3 ( string arg1 , int arg2 , float kwarg1 = 1.1f , bool kwarg2 = false , string kwarg3 = "" )
778+ {
779+ return "Method3 Overload 2" ;
780+ }
781+
782+ // ----
783+
784+ public string ImplicitConversionSameArgumentCount ( string symbol , int quantity , float trailingAmount , bool trailingAsPercentage , string tag = "" )
785+ {
786+ return "ImplicitConversionSameArgumentCount 1" ;
787+ }
788+
789+ public string ImplicitConversionSameArgumentCount ( string symbol , decimal quantity , decimal trailingAmount , bool trailingAsPercentage , string tag = "" )
790+ {
791+ return "ImplicitConversionSameArgumentCount 2" ;
792+ }
793+
794+ public string ImplicitConversionSameArgumentCount2 ( string symbol , int quantity , float trailingAmount , bool trailingAsPercentage , string tag = "" )
795+ {
796+ return "ImplicitConversionSameArgumentCount2 1" ;
797+ }
798+
799+ public string ImplicitConversionSameArgumentCount2 ( string symbol , float quantity , float trailingAmount , bool trailingAsPercentage , string tag = "" )
800+ {
801+ return "ImplicitConversionSameArgumentCount2 2" ;
802+ }
803+
804+ public string ImplicitConversionSameArgumentCount2 ( string symbol , decimal quantity , float trailingAmount , bool trailingAsPercentage , string tag = "" )
805+ {
806+ return "ImplicitConversionSameArgumentCount2 2" ;
807+ }
808+ }
809+
810+ [ TestCase ( "Method1('abc', namedArg1=10, namedArg2=321)" , "Method1 Overload 1" ) ]
811+ [ TestCase ( "Method1('abc', namedArg1=12.34, namedArg2=321)" , "Method1 Overload 1" ) ]
812+ [ TestCase ( "Method2(\" SPY\" , 10, 123, kwarg1=1, kwarg2=True)" , "Method2 Overload 1" ) ]
813+ [ TestCase ( "Method2(\" SPY\" , 10, 123.34, kwarg1=1.23, kwarg2=True)" , "Method2 Overload 1" ) ]
814+ [ TestCase ( "Method3(\" SPY\" , 10, 123.34, kwarg1=1.23, kwarg2=True)" , "Method3 Overload 1" ) ]
815+ public void SelectsRightOverloadWithNamedParameters ( string methodCallCode , string expectedResult )
816+ {
817+ using var _ = Py . GIL ( ) ;
818+
819+ dynamic module = PyModule . FromString ( "SelectsRightOverloadWithNamedParameters" , @$ "
820+
821+ def call_method(instance):
822+ return instance.{ methodCallCode }
823+ " ) ;
824+
825+ var instance = new OverloadsTestClass ( ) ;
826+ var result = module . call_method ( instance ) . As < string > ( ) ;
827+
828+ Assert . AreEqual ( expectedResult , result ) ;
829+ }
830+
831+ [ TestCase ( "ImplicitConversionSameArgumentCount" , "10" , "ImplicitConversionSameArgumentCount 1" ) ]
832+ [ TestCase ( "ImplicitConversionSameArgumentCount" , "10.1" , "ImplicitConversionSameArgumentCount 2" ) ]
833+ [ TestCase ( "ImplicitConversionSameArgumentCount2" , "10" , "ImplicitConversionSameArgumentCount2 1" ) ]
834+ [ TestCase ( "ImplicitConversionSameArgumentCount2" , "10.1" , "ImplicitConversionSameArgumentCount2 2" ) ]
835+ public void DisambiguatesOverloadWithSameArgumentCountAndImplicitConversion ( string methodName , string quantity , string expectedResult )
836+ {
837+ using var _ = Py . GIL ( ) ;
838+
839+ dynamic module = PyModule . FromString ( "DisambiguatesOverloadWithSameArgumentCountAndImplicitConversion" , @$ "
840+ def call_method(instance):
841+ return instance.{ methodName } (""SPY"", { quantity } , 123.4, trailingAsPercentage=True)
842+ " ) ;
843+
844+ var instance = new OverloadsTestClass ( ) ;
845+ var result = module . call_method ( instance ) . As < string > ( ) ;
846+
847+ Assert . AreEqual ( expectedResult , result ) ;
848+ }
849+
850+ public class CSharpClass
851+ {
852+ public string CalledMethodMessage { get ; private set ; }
853+
854+ public void Method ( )
855+ {
856+ CalledMethodMessage = "Overload 1" ;
857+ }
858+
859+ public void Method ( string stringArgument , decimal decimalArgument = 1.2m )
860+ {
861+ CalledMethodMessage = "Overload 2" ;
862+ }
863+
864+ public void Method ( PyObject typeArgument , decimal decimalArgument = 1.2m )
865+ {
866+ CalledMethodMessage = "Overload 3" ;
867+ }
868+ }
869+
870+ [ Test ]
871+ public void CallsCorrectOverloadWithoutErrors ( )
872+ {
873+ using var _ = Py . GIL ( ) ;
874+
875+ var module = PyModule . FromString ( "CallsCorrectOverloadWithoutErrors" , @"
876+ from clr import AddReference
877+ AddReference(""System"")
878+ AddReference(""Python.EmbeddingTest"")
879+ from Python.EmbeddingTest import *
880+
881+ class PythonModel(TestMethodBinder.CSharpModel):
882+ pass
883+
884+ def call_method(instance):
885+ instance.Method(PythonModel, decimalArgument=1.234)
886+ " ) ;
887+
888+ var instance = new CSharpClass ( ) ;
889+ using var pyInstance = instance . ToPython ( ) ;
890+
891+ Assert . DoesNotThrow ( ( ) =>
892+ {
893+ module . GetAttr ( "call_method" ) . Invoke ( pyInstance ) ;
894+ } ) ;
895+
896+ Assert . AreEqual ( "Overload 3" , instance . CalledMethodMessage ) ;
897+
898+ Assert . IsFalse ( Exceptions . ErrorOccurred ( ) ) ;
899+ }
900+
743901
744902 // Used to test that we match this function with Py DateTime & Date Objects
745903 public static int GetMonth ( DateTime test )
0 commit comments