Skip to content

Commit 3db752a

Browse files
committed
Fix type instance conversion
1 parent 72d052e commit 3db752a

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

src/embed_tests/TestConverter.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,27 @@ public void PrimitiveIntConversion()
450450
var testInt = pyValue.As<int>();
451451
Assert.AreEqual(testInt , 10);
452452
}
453+
454+
[TestCase(typeof(Type), true)]
455+
[TestCase(typeof(string), false)]
456+
[TestCase(typeof(TestCSharpModel), false)]
457+
public void NoErrorSetWhenFailingToConvertClassType(Type type, bool shouldConvert)
458+
{
459+
using var _ = Py.GIL();
460+
461+
var module = PyModule.FromString("CallsCorrectOverloadWithoutErrors", @"
462+
from clr import AddReference
463+
AddReference(""System"")
464+
AddReference(""Python.EmbeddingTest"")
465+
from Python.EmbeddingTest import *
466+
467+
class TestPythonModel(TestCSharpModel):
468+
pass
469+
");
470+
var testPythonModelClass = module.GetAttr("TestPythonModel");
471+
Assert.AreEqual(shouldConvert, Converter.ToManaged(testPythonModelClass, type, out var result, setError: false));
472+
Assert.IsFalse(Exceptions.ErrorOccurred());
473+
}
453474
}
454475

455476
public interface IGetList
@@ -461,4 +482,8 @@ public class GetListImpl : IGetList
461482
{
462483
public List<string> GetList() => new() { "testing" };
463484
}
485+
486+
public class TestCSharpModel
487+
{
488+
}
464489
}

src/embed_tests/TestMethodBinder.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,57 @@ from Python.EmbeddingTest import *
740740
"));
741741
}
742742

743+
public class CSharpClass
744+
{
745+
public string CalledMethodMessage { get; private set; }
746+
747+
public void Method()
748+
{
749+
CalledMethodMessage = "Overload 1";
750+
}
751+
752+
public void Method(string stringArgument, decimal decimalArgument = 1.2m)
753+
{
754+
CalledMethodMessage = "Overload 2";
755+
}
756+
757+
public void Method(PyObject typeArgument, decimal decimalArgument = 1.2m)
758+
{
759+
CalledMethodMessage = "Overload 3";
760+
}
761+
}
762+
763+
[Test]
764+
public void CallsCorrectOverloadWithoutErrors()
765+
{
766+
using var _ = Py.GIL();
767+
768+
var module = PyModule.FromString("CallsCorrectOverloadWithoutErrors", @"
769+
from clr import AddReference
770+
AddReference(""System"")
771+
AddReference(""Python.EmbeddingTest"")
772+
from Python.EmbeddingTest import *
773+
774+
class PythonModel(TestMethodBinder.CSharpModel):
775+
pass
776+
777+
def call_method(instance):
778+
instance.Method(PythonModel, decimalArgument=1.234)
779+
");
780+
781+
var instance = new CSharpClass();
782+
using var pyInstance = instance.ToPython();
783+
784+
Assert.DoesNotThrow(() =>
785+
{
786+
module.GetAttr("call_method").Invoke(pyInstance);
787+
});
788+
789+
Assert.AreEqual("Overload 3", instance.CalledMethodMessage);
790+
791+
Assert.IsFalse(Exceptions.ErrorOccurred());
792+
}
793+
743794

744795
// Used to test that we match this function with Py DateTime & Date Objects
745796
public static int GetMonth(DateTime test)

src/runtime/Converter.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,13 @@ internal static bool ToManagedValue(BorrowedReference value, Type obType,
473473
}
474474
if (mt is ClassBase cb)
475475
{
476-
if (!cb.type.Valid || !obType.IsInstanceOfType(cb.type.Value))
476+
// The value being converted is a class type, so it will only succeed if it's being converted into a Type
477+
if (obType != typeof(Type))
478+
{
479+
return false;
480+
}
481+
482+
if (!cb.type.Valid)
477483
{
478484
Exceptions.SetError(Exceptions.TypeError, cb.type.DeletedMessage);
479485
return false;

0 commit comments

Comments
 (0)