@@ -67,7 +67,7 @@ def TestEnumerable(self):
6767 public static dynamic Numpy ;
6868
6969 [ OneTimeSetUp ]
70- public void SetUp ( )
70+ public void OneTimeSetUp ( )
7171 {
7272 PythonEngine . Initialize ( ) ;
7373 using var _ = Py . GIL ( ) ;
@@ -89,6 +89,15 @@ public void Dispose()
8989 PythonEngine . Shutdown ( ) ;
9090 }
9191
92+ [ SetUp ]
93+ public void SetUp ( )
94+ {
95+ CSharpModel . LastDelegateCalled = null ;
96+ CSharpModel . LastFuncCalled = null ;
97+ CSharpModel . MethodCalled = null ;
98+ CSharpModel . ProvidedArgument = null ;
99+ }
100+
92101 [ Test ]
93102 public void MethodCalledList ( )
94103 {
@@ -1152,6 +1161,247 @@ def call_method():
11521161 Assert . AreEqual ( "MethodWithEnumParam With Enum" , result . As < string > ( ) ) ;
11531162 }
11541163
1164+ [ TestCase ( "call_method_with_func1" , "MethodWithFunc1" , "func1" ) ]
1165+ [ TestCase ( "call_method_with_func2" , "MethodWithFunc2" , "func2" ) ]
1166+ [ TestCase ( "call_method_with_func3" , "MethodWithFunc3" , "func3" ) ]
1167+ [ TestCase ( "call_method_with_func1_lambda" , "MethodWithFunc1" , "func1" ) ]
1168+ [ TestCase ( "call_method_with_func2_lambda" , "MethodWithFunc2" , "func2" ) ]
1169+ [ TestCase ( "call_method_with_func3_lambda" , "MethodWithFunc3" , "func3" ) ]
1170+ public void BindsPythonToCSharpFuncDelegates ( string pythonFuncToCall , string expectedCSharpMethodCalled , string expectedPythonFuncCalled )
1171+ {
1172+ using var _ = Py . GIL ( ) ;
1173+
1174+ var module = PyModule . FromString ( "BindsPythonToCSharpFuncDelegates" , @$ "
1175+ from clr import AddReference
1176+ AddReference(""System"")
1177+ from Python.EmbeddingTest import *
1178+
1179+ from System import Func
1180+
1181+ class PythonModel:
1182+ last_delegate_called = None
1183+
1184+ def func1():
1185+ PythonModel.last_delegate_called = 'func1'
1186+ return TestMethodBinder.CSharpModel();
1187+
1188+ def func2(model):
1189+ if model is None or not isinstance(model, TestMethodBinder.CSharpModel):
1190+ raise TypeError(""model must be of type CSharpModel"")
1191+ PythonModel.last_delegate_called = 'func2'
1192+ return model
1193+
1194+ def func3(model1, model2):
1195+ if model1 is None or model2 is None or not isinstance(model1, TestMethodBinder.CSharpModel) or not isinstance(model2, TestMethodBinder.CSharpModel):
1196+ raise TypeError(""model1 and model2 must be of type CSharpModel"")
1197+ PythonModel.last_delegate_called = 'func3'
1198+ return model1
1199+
1200+ def call_method_with_func1():
1201+ return TestMethodBinder.CSharpModel.MethodWithFunc1(func1)
1202+
1203+ def call_method_with_func2():
1204+ return TestMethodBinder.CSharpModel.MethodWithFunc2(func2)
1205+
1206+ def call_method_with_func3():
1207+ return TestMethodBinder.CSharpModel.MethodWithFunc3(func3)
1208+
1209+ def call_method_with_func1_lambda():
1210+ return TestMethodBinder.CSharpModel.MethodWithFunc1(lambda: func1())
1211+
1212+ def call_method_with_func2_lambda():
1213+ return TestMethodBinder.CSharpModel.MethodWithFunc2(lambda model: func2(model))
1214+
1215+ def call_method_with_func3_lambda():
1216+ return TestMethodBinder.CSharpModel.MethodWithFunc3(lambda model1, model2: func3(model1, model2))
1217+ " ) ;
1218+
1219+ CSharpModel managedResult = null ;
1220+ Assert . DoesNotThrow ( ( ) =>
1221+ {
1222+ using var result = module . GetAttr ( pythonFuncToCall ) . Invoke ( ) ;
1223+ managedResult = result . As < CSharpModel > ( ) ;
1224+ } ) ;
1225+
1226+ Assert . IsNotNull ( managedResult ) ;
1227+ Assert . AreEqual ( expectedCSharpMethodCalled , CSharpModel . LastDelegateCalled ) ;
1228+
1229+ using var pythonModel = module . GetAttr ( "PythonModel" ) ;
1230+ using var lastDelegateCalled = pythonModel . GetAttr ( "last_delegate_called" ) ;
1231+ Assert . AreEqual ( expectedPythonFuncCalled , lastDelegateCalled . As < string > ( ) ) ;
1232+ }
1233+
1234+ [ TestCase ( "call_method_with_action1" , "MethodWithAction1" , "action1" ) ]
1235+ [ TestCase ( "call_method_with_action2" , "MethodWithAction2" , "action2" ) ]
1236+ [ TestCase ( "call_method_with_action3" , "MethodWithAction3" , "action3" ) ]
1237+ [ TestCase ( "call_method_with_action1_lambda" , "MethodWithAction1" , "action1" ) ]
1238+ [ TestCase ( "call_method_with_action2_lambda" , "MethodWithAction2" , "action2" ) ]
1239+ [ TestCase ( "call_method_with_action3_lambda" , "MethodWithAction3" , "action3" ) ]
1240+ public void BindsPythonToCSharpActionDelegates ( string pythonFuncToCall , string expectedCSharpMethodCalled , string expectedPythonFuncCalled )
1241+ {
1242+ using var _ = Py . GIL ( ) ;
1243+
1244+ var module = PyModule . FromString ( "BindsPythonToCSharpActionDelegates" , @$ "
1245+ from clr import AddReference
1246+ AddReference(""System"")
1247+ from Python.EmbeddingTest import *
1248+
1249+ from System import Func
1250+
1251+ class PythonModel:
1252+ last_delegate_called = None
1253+
1254+ def action1():
1255+ PythonModel.last_delegate_called = 'action1'
1256+ pass
1257+
1258+ def action2(model):
1259+ if model is None or not isinstance(model, TestMethodBinder.CSharpModel):
1260+ raise TypeError(""model must be of type CSharpModel"")
1261+ PythonModel.last_delegate_called = 'action2'
1262+ pass
1263+
1264+ def action3(model1, model2):
1265+ if model1 is None or model2 is None or not isinstance(model1, TestMethodBinder.CSharpModel) or not isinstance(model2, TestMethodBinder.CSharpModel):
1266+ raise TypeError(""model1 and model2 must be of type CSharpModel"")
1267+ PythonModel.last_delegate_called = 'action3'
1268+ pass
1269+
1270+ def call_method_with_action1():
1271+ return TestMethodBinder.CSharpModel.MethodWithAction1(action1)
1272+
1273+ def call_method_with_action2():
1274+ return TestMethodBinder.CSharpModel.MethodWithAction2(action2)
1275+
1276+ def call_method_with_action3():
1277+ return TestMethodBinder.CSharpModel.MethodWithAction3(action3)
1278+
1279+ def call_method_with_action1_lambda():
1280+ return TestMethodBinder.CSharpModel.MethodWithAction1(lambda: action1())
1281+
1282+ def call_method_with_action2_lambda():
1283+ return TestMethodBinder.CSharpModel.MethodWithAction2(lambda model: action2(model))
1284+
1285+ def call_method_with_action3_lambda():
1286+ return TestMethodBinder.CSharpModel.MethodWithAction3(lambda model1, model2: action3(model1, model2))
1287+ " ) ;
1288+
1289+ Assert . DoesNotThrow ( ( ) =>
1290+ {
1291+ using var result = module . GetAttr ( pythonFuncToCall ) . Invoke ( ) ;
1292+ } ) ;
1293+
1294+ Assert . AreEqual ( expectedCSharpMethodCalled , CSharpModel . LastDelegateCalled ) ;
1295+
1296+ using var pythonModel = module . GetAttr ( "PythonModel" ) ;
1297+ using var lastDelegateCalled = pythonModel . GetAttr ( "last_delegate_called" ) ;
1298+ Assert . AreEqual ( expectedPythonFuncCalled , lastDelegateCalled . As < string > ( ) ) ;
1299+ }
1300+
1301+ [ TestCase ( "call_method_with_func1" , "MethodWithFunc1" , "TestFunc1" ) ]
1302+ [ TestCase ( "call_method_with_func2" , "MethodWithFunc2" , "TestFunc2" ) ]
1303+ [ TestCase ( "call_method_with_func3" , "MethodWithFunc3" , "TestFunc3" ) ]
1304+ public void BindsCSharpFuncFromPythonToCSharpFuncDelegates ( string pythonFuncToCall , string expectedMethodCalled , string expectedInnerMethodCalled )
1305+ {
1306+ using var _ = Py . GIL ( ) ;
1307+
1308+ var module = PyModule . FromString ( "BindsCSharpFuncFromPythonToCSharpFuncDelegates" , @$ "
1309+ from clr import AddReference
1310+ AddReference(""System"")
1311+ from Python.EmbeddingTest import *
1312+
1313+ def call_method_with_func1():
1314+ return TestMethodBinder.CSharpModel.MethodWithFunc1(TestMethodBinder.CSharpModel.TestFunc1)
1315+
1316+ def call_method_with_func2():
1317+ return TestMethodBinder.CSharpModel.MethodWithFunc2(TestMethodBinder.CSharpModel.TestFunc2)
1318+
1319+ def call_method_with_func3():
1320+ return TestMethodBinder.CSharpModel.MethodWithFunc3(TestMethodBinder.CSharpModel.TestFunc3)
1321+ " ) ;
1322+
1323+ CSharpModel managedResult = null ;
1324+ Assert . DoesNotThrow ( ( ) =>
1325+ {
1326+ using var result = module . GetAttr ( pythonFuncToCall ) . Invoke ( ) ;
1327+ managedResult = result . As < CSharpModel > ( ) ;
1328+ } ) ;
1329+ Assert . IsNotNull ( managedResult ) ;
1330+ Assert . AreEqual ( expectedMethodCalled , CSharpModel . LastDelegateCalled ) ;
1331+ Assert . AreEqual ( expectedInnerMethodCalled , CSharpModel . LastFuncCalled ) ;
1332+ }
1333+
1334+ [ TestCase ( "call_method_with_action1" , "MethodWithAction1" , "TestAction1" ) ]
1335+ [ TestCase ( "call_method_with_action2" , "MethodWithAction2" , "TestAction2" ) ]
1336+ [ TestCase ( "call_method_with_action3" , "MethodWithAction3" , "TestAction3" ) ]
1337+ public void BindsCSharpActionFromPythonToCSharpActionDelegates ( string pythonFuncToCall , string expectedMethodCalled , string expectedInnerMethodCalled )
1338+ {
1339+ using var _ = Py . GIL ( ) ;
1340+
1341+ var module = PyModule . FromString ( "BindsCSharpActionFromPythonToCSharpActionDelegates" , @$ "
1342+ from clr import AddReference
1343+ AddReference(""System"")
1344+ from Python.EmbeddingTest import *
1345+
1346+ def call_method_with_action1():
1347+ return TestMethodBinder.CSharpModel.MethodWithAction1(TestMethodBinder.CSharpModel.TestAction1)
1348+
1349+ def call_method_with_action2():
1350+ return TestMethodBinder.CSharpModel.MethodWithAction2(TestMethodBinder.CSharpModel.TestAction2)
1351+
1352+ def call_method_with_action3():
1353+ return TestMethodBinder.CSharpModel.MethodWithAction3(TestMethodBinder.CSharpModel.TestAction3)
1354+ " ) ;
1355+
1356+ Assert . DoesNotThrow ( ( ) =>
1357+ {
1358+ using var result = module . GetAttr ( pythonFuncToCall ) . Invoke ( ) ;
1359+ } ) ;
1360+ Assert . AreEqual ( expectedMethodCalled , CSharpModel . LastDelegateCalled ) ;
1361+ Assert . AreEqual ( expectedInnerMethodCalled , CSharpModel . LastFuncCalled ) ;
1362+ }
1363+
1364+ [ Test ]
1365+ public void NumericArgumentsTakePrecedenceOverEnums ( )
1366+ {
1367+ using var _ = Py . GIL ( ) ;
1368+
1369+ var module = PyModule . FromString ( "NumericArgumentsTakePrecedenceOverEnums" , @$ "
1370+ from clr import AddReference
1371+ AddReference(""System"")
1372+ from Python.EmbeddingTest import *
1373+ from System import DayOfWeek
1374+
1375+ def call_method_with_int():
1376+ TestMethodBinder.CSharpModel().NumericalArgumentMethod(1)
1377+
1378+ def call_method_with_float():
1379+ TestMethodBinder.CSharpModel().NumericalArgumentMethod(0.1)
1380+
1381+ def call_method_with_numpy_float():
1382+ TestMethodBinder.CSharpModel().NumericalArgumentMethod(TestMethodBinder.Numpy.float64(0.1))
1383+
1384+ def call_method_with_enum():
1385+ TestMethodBinder.CSharpModel().NumericalArgumentMethod(DayOfWeek.MONDAY)
1386+ " ) ;
1387+
1388+ module . GetAttr ( "call_method_with_int" ) . Invoke ( ) ;
1389+ Assert . AreEqual ( typeof ( int ) , CSharpModel . ProvidedArgument . GetType ( ) ) ;
1390+ Assert . AreEqual ( 1 , CSharpModel . ProvidedArgument ) ;
1391+
1392+ module . GetAttr ( "call_method_with_float" ) . Invoke ( ) ;
1393+ Assert . AreEqual ( typeof ( double ) , CSharpModel . ProvidedArgument . GetType ( ) ) ;
1394+ Assert . AreEqual ( 0.1d , CSharpModel . ProvidedArgument ) ;
1395+
1396+ module . GetAttr ( "call_method_with_numpy_float" ) . Invoke ( ) ;
1397+ Assert . AreEqual ( typeof ( decimal ) , CSharpModel . ProvidedArgument . GetType ( ) ) ;
1398+ Assert . AreEqual ( 0.1m , CSharpModel . ProvidedArgument ) ;
1399+
1400+ module . GetAttr ( "call_method_with_enum" ) . Invoke ( ) ;
1401+ Assert . AreEqual ( typeof ( DayOfWeek ) , CSharpModel . ProvidedArgument . GetType ( ) ) ;
1402+ Assert . AreEqual ( DayOfWeek . Monday , CSharpModel . ProvidedArgument ) ;
1403+ }
1404+
11551405 // Used to test that we match this function with Py DateTime & Date Objects
11561406 public static int GetMonth ( DateTime test )
11571407 {
@@ -1234,6 +1484,10 @@ public void NumericalArgumentMethod(decimal value)
12341484 {
12351485 ProvidedArgument = value ;
12361486 }
1487+ public void NumericalArgumentMethod ( DayOfWeek value )
1488+ {
1489+ ProvidedArgument = value ;
1490+ }
12371491 public void EnumerableKeyValuePair ( IEnumerable < KeyValuePair < string , decimal > > value )
12381492 {
12391493 ProvidedArgument = value ;
@@ -1288,6 +1542,100 @@ public static void MethodDateTimeAndTimeSpan(CSharpModel pepe, Func<DateTime, Da
12881542 {
12891543 AssertErrorNotOccurred ( ) ;
12901544 }
1545+
1546+ public static string LastDelegateCalled { get ; set ; }
1547+ public static string LastFuncCalled { get ; set ; }
1548+
1549+ public static CSharpModel MethodWithFunc1 ( Func < CSharpModel > func )
1550+ {
1551+ AssertErrorNotOccurred ( ) ;
1552+ LastDelegateCalled = "MethodWithFunc1" ;
1553+ return func ( ) ;
1554+ }
1555+
1556+ public static CSharpModel MethodWithFunc2 ( Func < CSharpModel , CSharpModel > func )
1557+ {
1558+ AssertErrorNotOccurred ( ) ;
1559+ LastDelegateCalled = "MethodWithFunc2" ;
1560+ return func ( new CSharpModel ( ) ) ;
1561+ }
1562+
1563+ public static CSharpModel MethodWithFunc3 ( Func < CSharpModel , CSharpModel , CSharpModel > func )
1564+ {
1565+ AssertErrorNotOccurred ( ) ;
1566+ LastDelegateCalled = "MethodWithFunc3" ;
1567+ return func ( new CSharpModel ( ) , new CSharpModel ( ) ) ;
1568+ }
1569+
1570+ public static void MethodWithAction1 ( Action action )
1571+ {
1572+ AssertErrorNotOccurred ( ) ;
1573+ LastDelegateCalled = "MethodWithAction1" ;
1574+ action ( ) ;
1575+ }
1576+
1577+ public static void MethodWithAction2 ( Action < CSharpModel > action )
1578+ {
1579+ AssertErrorNotOccurred ( ) ;
1580+ LastDelegateCalled = "MethodWithAction2" ;
1581+ action ( new CSharpModel ( ) ) ;
1582+ }
1583+
1584+ public static void MethodWithAction3 ( Action < CSharpModel , CSharpModel > action )
1585+ {
1586+ AssertErrorNotOccurred ( ) ;
1587+ LastDelegateCalled = "MethodWithAction3" ;
1588+ action ( new CSharpModel ( ) , new CSharpModel ( ) ) ;
1589+ }
1590+
1591+ public static CSharpModel TestFunc1 ( )
1592+ {
1593+ LastFuncCalled = "TestFunc1" ;
1594+ return new CSharpModel ( ) ;
1595+ }
1596+
1597+ public static CSharpModel TestFunc2 ( CSharpModel model )
1598+ {
1599+ if ( model == null )
1600+ {
1601+ throw new ArgumentNullException ( nameof ( model ) ) ;
1602+ }
1603+ LastFuncCalled = "TestFunc2" ;
1604+ return model ;
1605+ }
1606+
1607+ public static CSharpModel TestFunc3 ( CSharpModel model1 , CSharpModel model2 )
1608+ {
1609+ if ( model1 == null || model2 == null )
1610+ {
1611+ throw new ArgumentNullException ( model1 == null ? nameof ( model1 ) : nameof ( model2 ) ) ;
1612+ }
1613+ LastFuncCalled = "TestFunc3" ;
1614+ return model1 ;
1615+ }
1616+
1617+ public static void TestAction1 ( )
1618+ {
1619+ LastFuncCalled = "TestAction1" ;
1620+ }
1621+
1622+ public static void TestAction2 ( CSharpModel model )
1623+ {
1624+ if ( model == null )
1625+ {
1626+ throw new ArgumentNullException ( nameof ( model ) ) ;
1627+ }
1628+ LastFuncCalled = "TestAction2" ;
1629+ }
1630+
1631+ public static void TestAction3 ( CSharpModel model1 , CSharpModel model2 )
1632+ {
1633+ if ( model1 == null || model2 == null )
1634+ {
1635+ throw new ArgumentNullException ( model1 == null ? nameof ( model1 ) : nameof ( model2 ) ) ;
1636+ }
1637+ LastFuncCalled = "TestAction3" ;
1638+ }
12911639 }
12921640
12931641 public class TestImplicitConversion
0 commit comments