diff --git a/src/embed_tests/Codecs.cs b/src/embed_tests/Codecs.cs index f0c00a6d8..e7303a8e4 100644 --- a/src/embed_tests/Codecs.cs +++ b/src/embed_tests/Codecs.cs @@ -355,6 +355,24 @@ public void ExceptionDecoded() Assert.AreEqual(TestExceptionMessage, error.Message); } + [Test] + public void DateTimeDecoded() + { + using var scope = Py.CreateScope(); + scope.Exec(@" +import clr +from datetime import datetime + + +from Python.EmbeddingTest import Codecs, DateTimeDecoder + +DateTimeDecoder.Setup() +"); + scope.Exec("Codecs.AcceptsDateTime(datetime(2021, 1, 22))"); + } + + public static void AcceptsDateTime(DateTime v) {} + class ValueErrorWrapper : Exception { public ValueErrorWrapper(string message) : base(message) { } @@ -419,4 +437,30 @@ public bool TryDecode(PyObject pyObj, out T value) return true; } } + + public class DateTimeDecoder : IPyObjectDecoder + { + public static void Setup() + { + PyObjectConversions.RegisterDecoder(new DateTimeDecoder()); + } + + public bool CanDecode(PyObject objectType, Type targetType) + { + return targetType == typeof(DateTime); + } + + public bool TryDecode(PyObject pyObj, out T value) + { + var dt = new DateTime( + pyObj.GetAttr("year").As(), + pyObj.GetAttr("month").As(), + pyObj.GetAttr("day").As(), + pyObj.GetAttr("hour").As(), + pyObj.GetAttr("minute").As(), + pyObj.GetAttr("second").As()); + value = (T)(object)dt; + return true; + } + } } diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 936f8b248..420fc9435 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -149,11 +149,8 @@ internal static IntPtr ToPython(object value, Type type) return result; } - if (Type.GetTypeCode(type) == TypeCode.Object - && value.GetType() != typeof(object) - && value is not Type - || type.IsEnum - ) { + if (EncodableByUser(type, value)) + { var encoded = PyObjectConversions.TryEncode(value, type); if (encoded != null) { result = encoded.Handle; @@ -301,6 +298,13 @@ internal static IntPtr ToPython(object value, Type type) } } + static bool EncodableByUser(Type type, object value) + { + TypeCode typeCode = Type.GetTypeCode(type); + return type.IsEnum + || typeCode is TypeCode.DateTime or TypeCode.Decimal + || typeCode == TypeCode.Object && value.GetType() != typeof(object) && value is not Type; + } /// /// In a few situations, we don't have any advisory type information @@ -523,8 +527,7 @@ internal static bool ToManagedValue(IntPtr value, Type obType, return false; } - TypeCode typeCode = Type.GetTypeCode(obType); - if (typeCode == TypeCode.Object || obType.IsEnum) + if (DecodableByUser(obType)) { IntPtr pyType = Runtime.PyObject_TYPE(value); if (PyObjectConversions.TryDecode(value, pyType, obType, out result)) @@ -536,6 +539,13 @@ internal static bool ToManagedValue(IntPtr value, Type obType, return ToPrimitive(value, obType, out result, setError); } + static bool DecodableByUser(Type type) + { + TypeCode typeCode = Type.GetTypeCode(type); + return type.IsEnum + || typeCode is TypeCode.Object or TypeCode.Decimal or TypeCode.DateTime; + } + internal delegate bool TryConvertFromPythonDelegate(IntPtr pyObj, out object result); internal static int ToInt32(BorrowedReference value) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy