Skip to content

Commit c799b7e

Browse files
committed
Fix: PyObject array overloads precedence
1 parent c69fb42 commit c799b7e

File tree

3 files changed

+83
-12
lines changed

3 files changed

+83
-12
lines changed

src/embed_tests/TestMethodBinder.cs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,34 @@ public string ImplicitConversionSameArgumentCount2(string symbol, decimal quanti
805805
{
806806
return "ImplicitConversionSameArgumentCount2 2";
807807
}
808+
809+
// ----
810+
811+
public string VariableArgumentsMethod(params CSharpModel[] paramsParams)
812+
{
813+
return "VariableArgumentsMethod(CSharpModel[])";
814+
}
815+
816+
public string VariableArgumentsMethod(params PyObject[] paramsParams)
817+
{
818+
return "VariableArgumentsMethod(PyObject[])";
819+
}
820+
821+
public string ConstructorMessage { get; set; }
822+
823+
public OverloadsTestClass(params CSharpModel[] paramsParams)
824+
{
825+
ConstructorMessage = "OverloadsTestClass(CSharpModel[])";
826+
}
827+
828+
public OverloadsTestClass(params PyObject[] paramsParams)
829+
{
830+
ConstructorMessage = "OverloadsTestClass(PyObject[])";
831+
}
832+
833+
public OverloadsTestClass()
834+
{
835+
}
808836
}
809837

810838
[TestCase("Method1('abc', namedArg1=10, namedArg2=321)", "Method1 Overload 1")]
@@ -907,7 +935,7 @@ public void BindsConstructorToSnakeCasedArgumentsVersion([Values] bool useCamelC
907935
var argument2Name = useCamelCase ? "anotherArgument" : "another_argument";
908936
var argument2Code = passOptionalArgument ? $", {argument2Name}=\"another argument value\"" : "";
909937

910-
var module = PyModule.FromString("CallsCorrectOverloadWithoutErrors", @$"
938+
var module = PyModule.FromString("BindsConstructorToSnakeCasedArgumentsVersion", @$"
911939
from clr import AddReference
912940
AddReference(""System"")
913941
from Python.EmbeddingTest import *
@@ -925,6 +953,49 @@ def create_instance():
925953
Assert.AreEqual(expectedMessage, sourceException.Message);
926954
}
927955

956+
[Test]
957+
public void PyObjectArrayHasPrecedenceOverOtherTypeArrays()
958+
{
959+
using var _ = Py.GIL();
960+
961+
var module = PyModule.FromString("PyObjectArrayHasPrecedenceOverOtherTypeArrays", @$"
962+
from clr import AddReference
963+
AddReference(""System"")
964+
from Python.EmbeddingTest import *
965+
966+
class PythonModel(TestMethodBinder.CSharpModel):
967+
pass
968+
969+
def call_method():
970+
return TestMethodBinder.OverloadsTestClass().VariableArgumentsMethod(PythonModel(), PythonModel())
971+
");
972+
973+
var result = module.GetAttr("call_method").Invoke().As<string>();
974+
Assert.AreEqual("VariableArgumentsMethod(PyObject[])", result);
975+
}
976+
977+
[Test]
978+
public void PyObjectArrayHasPrecedenceOverOtherTypeArraysInConstructors()
979+
{
980+
using var _ = Py.GIL();
981+
982+
var module = PyModule.FromString("PyObjectArrayHasPrecedenceOverOtherTypeArrays", @$"
983+
from clr import AddReference
984+
AddReference(""System"")
985+
from Python.EmbeddingTest import *
986+
987+
class PythonModel(TestMethodBinder.CSharpModel):
988+
pass
989+
990+
def get_instance():
991+
return TestMethodBinder.OverloadsTestClass(PythonModel(), PythonModel())
992+
");
993+
994+
var instance = module.GetAttr("get_instance").Invoke();
995+
Assert.AreEqual("OverloadsTestClass(PyObject[])", instance.GetAttr("ConstructorMessage").As<string>());
996+
}
997+
998+
928999
// Used to test that we match this function with Py DateTime & Date Objects
9291000
public static int GetMonth(DateTime test)
9301001
{

src/runtime/ClassManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ void AddMember(string name, string snakeCasedName, bool isStaticReadonlyCallable
553553
}
554554
methodList.Add(ctor, true);
555555
// Same constructor, but with snake-cased arguments
556-
if (ctor.GetParameters().Any(pi => pi.Name.ToSnakeCase() != pi.Name))
556+
if (ctor.GetParameters().Any(pi => pi.Name?.ToSnakeCase() != pi.Name))
557557
{
558558
methodList.Add(ctor, false);
559559
}

src/runtime/MethodBinder.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,16 @@ internal static int ArgPrecedence(Type t, MethodInformation mi)
365365
return -1;
366366
}
367367

368+
if (t.IsArray)
369+
{
370+
Type e = t.GetElementType();
371+
if (e == objectType)
372+
{
373+
return 2500;
374+
}
375+
return 100 + ArgPrecedence(e, mi);
376+
}
377+
368378
TypeCode tc = Type.GetTypeCode(t);
369379
// TODO: Clean up
370380
switch (tc)
@@ -406,16 +416,6 @@ internal static int ArgPrecedence(Type t, MethodInformation mi)
406416
return 40;
407417
}
408418

409-
if (t.IsArray)
410-
{
411-
Type e = t.GetElementType();
412-
if (e == objectType)
413-
{
414-
return 2500;
415-
}
416-
return 100 + ArgPrecedence(e, mi);
417-
}
418-
419419
return 2000;
420420
}
421421

0 commit comments

Comments
 (0)