| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9555248 commit 4b7a23c
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -355,6 +355,24 @@ public void ExceptionDecoded() | |||
| 355 | 355 | Assert.AreEqual(TestExceptionMessage, error.Message); | |
| 356 | 356 | } | |
| 357 | 357 | ||
| 358 | + [Test] | ||
| 359 | + public void DateTimeDecoded() | ||
| 360 | + { | ||
| 361 | + using var scope = Py.CreateScope(); | ||
| 362 | + scope.Exec(@" | ||
| 363 | + import clr | ||
| 364 | + from datetime import datetime | ||
| 365 | + | ||
| 366 | + | ||
| 367 | + from Python.EmbeddingTest import Codecs, DateTimeDecoder | ||
| 368 | + | ||
| 369 | + DateTimeDecoder.Setup() | ||
| 370 | + "); | ||
| 371 | + scope.Exec("Codecs.AcceptsDateTime(datetime(2021, 1, 22))"); | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + public static void AcceptsDateTime(DateTime v) {} | ||
| 375 | + | ||
| 358 | 376 | class ValueErrorWrapper : Exception | |
| 359 | 377 | { | |
| 360 | 378 | public ValueErrorWrapper(string message) : base(message) { } | |
@@ -419,4 +437,30 @@ public bool TryDecode<T>(PyObject pyObj, out T value) | |||
| 419 | 437 | return true; | |
| 420 | 438 | } | |
| 421 | 439 | } | |
| 440 | + | ||
| 441 | + public class DateTimeDecoder : IPyObjectDecoder | ||
| 442 | + { | ||
| 443 | + public static void Setup() | ||
| 444 | + { | ||
| 445 | + PyObjectConversions.RegisterDecoder(new DateTimeDecoder()); | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + public bool CanDecode(PyObject objectType, Type targetType) | ||
| 449 | + { | ||
| 450 | + return targetType == typeof(DateTime); | ||
| 451 | + } | ||
| 452 | + | ||
| 453 | + public bool TryDecode<T>(PyObject pyObj, out T value) | ||
| 454 | + { | ||
| 455 | + var dt = new DateTime( | ||
| 456 | + pyObj.GetAttr("year").As<int>(), | ||
| 457 | + pyObj.GetAttr("month").As<int>(), | ||
| 458 | + pyObj.GetAttr("day").As<int>(), | ||
| 459 | + pyObj.GetAttr("hour").As<int>(), | ||
| 460 | + pyObj.GetAttr("minute").As<int>(), | ||
| 461 | + pyObj.GetAttr("second").As<int>()); | ||
| 462 | + value = (T)(object)dt; | ||
| 463 | + return true; | ||
| 464 | + } | ||
| 465 | + } | ||
| 422 | 466 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -149,11 +149,8 @@ internal static IntPtr ToPython(object value, Type type) | |||
| 149 | 149 | return result; | |
| 150 | 150 | } | |
| 151 | 151 | ||
| 152 | - if (Type.GetTypeCode(type) == TypeCode.Object | ||
| 153 | - && value.GetType() != typeof(object) | ||
| 154 | - && value is not Type | ||
| 155 | - || type.IsEnum | ||
| 156 | - ) { | ||
| 152 | + if (EncodableByUser(type, value)) | ||
| 153 | + { | ||
| 157 | 154 | var encoded = PyObjectConversions.TryEncode(value, type); | |
| 158 | 155 | if (encoded != null) { | |
| 159 | 156 | result = encoded.Handle; | |
@@ -301,6 +298,13 @@ internal static IntPtr ToPython(object value, Type type) | |||
| 301 | 298 | } | |
| 302 | 299 | } | |
| 303 | 300 | ||
| 301 | + static bool EncodableByUser(Type type, object value) | ||
| 302 | + { | ||
| 303 | + TypeCode typeCode = Type.GetTypeCode(type); | ||
| 304 | + return type.IsEnum | ||
| 305 | + || typeCode is TypeCode.DateTime or TypeCode.Decimal | ||
| 306 | + || typeCode == TypeCode.Object && value.GetType() != typeof(object) && value is not Type; | ||
| 307 | + } | ||
| 304 | 308 | ||
| 305 | 309 | /// <summary> | |
| 306 | 310 | /// In a few situations, we don't have any advisory type information | |
@@ -523,8 +527,7 @@ internal static bool ToManagedValue(IntPtr value, Type obType, | |||
| 523 | 527 | return false; | |
| 524 | 528 | } | |
| 525 | 529 | ||
| 526 | - TypeCode typeCode = Type.GetTypeCode(obType); | ||
| 527 | - if (typeCode == TypeCode.Object || obType.IsEnum) | ||
| 530 | + if (DecodableByUser(obType)) | ||
| 528 | 531 | { | |
| 529 | 532 | IntPtr pyType = Runtime.PyObject_TYPE(value); | |
| 530 | 533 | if (PyObjectConversions.TryDecode(value, pyType, obType, out result)) | |
@@ -536,6 +539,13 @@ internal static bool ToManagedValue(IntPtr value, Type obType, | |||
| 536 | 539 | return ToPrimitive(value, obType, out result, setError); | |
| 537 | 540 | } | |
| 538 | 541 | ||
| 542 | + static bool DecodableByUser(Type type) | ||
| 543 | + { | ||
| 544 | + TypeCode typeCode = Type.GetTypeCode(type); | ||
| 545 | + return type.IsEnum | ||
| 546 | + || typeCode is TypeCode.Object or TypeCode.Decimal or TypeCode.DateTime; | ||
| 547 | + } | ||
| 548 | + | ||
| 539 | 549 | internal delegate bool TryConvertFromPythonDelegate(IntPtr pyObj, out object result); | |
| 540 | 550 | ||
| 541 | 551 | internal static int ToInt32(BorrowedReference value) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments