diff --git a/CHANGELOG.md b/CHANGELOG.md index e5f262620..b565fbbdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ One must now either use enum members (e.g. `MyEnum.Option`), or use enum constru - Sign Runtime DLL with a strong name - Implement loading through `clr_loader` instead of the included `ClrModule`, enables support for .NET Core +- BREAKING: custom encoders are no longer called for instances of `System.Type` ### Fixed diff --git a/src/embed_tests/Codecs.cs b/src/embed_tests/Codecs.cs index 266badb9e..de5882b32 100644 --- a/src/embed_tests/Codecs.cs +++ b/src/embed_tests/Codecs.cs @@ -296,6 +296,32 @@ public void IterableDecoderTest() Assert.DoesNotThrow(() => { codec.TryDecode(pyList, out intEnumerable); }); CollectionAssert.AreEqual(intEnumerable, new List { 1, 2, 3 }); } + + // regression for https://github.com/pythonnet/pythonnet/issues/1427 + [Ignore("https://github.com/pythonnet/pythonnet/issues/1256")] + [Test] + public void PythonRegisteredDecoder_NoStackOverflowOnSystemType() + { + const string PyCode = @" +import clr +import System +from Python.Runtime import PyObjectConversions +from Python.Runtime.Codecs import RawProxyEncoder + + +class ListAsRawEncoder(RawProxyEncoder): + __namespace__ = 'Dummy' + def CanEncode(self, clr_type): + return clr_type.Name == 'IList`1' and clr_type.Namespace == 'System.Collections.Generic' + + +list_encoder = ListAsRawEncoder() +PyObjectConversions.RegisterEncoder(list_encoder) + +system_type = list_encoder.GetType()"; + + PythonEngine.Exec(PyCode); + } } /// diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 4de334b5f..cd9477a62 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -146,8 +146,11 @@ internal static IntPtr ToPython(object value, Type type) return result; } - if (Type.GetTypeCode(type) == TypeCode.Object && value.GetType() != typeof(object) - || type.IsEnum) { + if (Type.GetTypeCode(type) == TypeCode.Object + && value.GetType() != typeof(object) + && value is not Type + || type.IsEnum + ) { var encoded = PyObjectConversions.TryEncode(value, type); if (encoded != null) { result = encoded.Handle;