From bec9563d2958acc5adf3e8972b23609fe3914402 Mon Sep 17 00:00:00 2001 From: AlexCatarino Date: Thu, 23 Aug 2018 23:27:02 +0100 Subject: [PATCH] Do not include timezone if DateTimeKind is Unspecified DECREF'ing datetime timezone argument when DateTimeKind is Unspecified was causing `Fatal Python error: deallocating None` because the object was set to `Runtime.PyNone`. Fixed the input to datetime constructor as we were passing milliseconds, where it should be microseconds. --- src/runtime/converter.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index ad8a8af02..a33ade002 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -292,15 +292,27 @@ internal static IntPtr ToPython(object value, Type type) case TypeCode.DateTime: var datetime = (DateTime)value; - IntPtr dateTimeArgs = Runtime.PyTuple_New(8); + var size = datetime.Kind == DateTimeKind.Unspecified ? 7 : 8; + + IntPtr dateTimeArgs = Runtime.PyTuple_New(size); Runtime.PyTuple_SetItem(dateTimeArgs, 0, Runtime.PyInt_FromInt32(datetime.Year)); Runtime.PyTuple_SetItem(dateTimeArgs, 1, Runtime.PyInt_FromInt32(datetime.Month)); Runtime.PyTuple_SetItem(dateTimeArgs, 2, Runtime.PyInt_FromInt32(datetime.Day)); Runtime.PyTuple_SetItem(dateTimeArgs, 3, Runtime.PyInt_FromInt32(datetime.Hour)); Runtime.PyTuple_SetItem(dateTimeArgs, 4, Runtime.PyInt_FromInt32(datetime.Minute)); Runtime.PyTuple_SetItem(dateTimeArgs, 5, Runtime.PyInt_FromInt32(datetime.Second)); - Runtime.PyTuple_SetItem(dateTimeArgs, 6, Runtime.PyInt_FromInt32(datetime.Millisecond)); - Runtime.PyTuple_SetItem(dateTimeArgs, 7, TzInfo(datetime.Kind)); + + // datetime.datetime 6th argument represents micro seconds + var totalSeconds = datetime.TimeOfDay.TotalSeconds; + var microSeconds = Convert.ToInt32((totalSeconds - Math.Truncate(totalSeconds)) * 1000000); + if (microSeconds == 1000000) microSeconds = 999999; + Runtime.PyTuple_SetItem(dateTimeArgs, 6, Runtime.PyInt_FromInt32(microSeconds)); + + if (size == 8) + { + Runtime.PyTuple_SetItem(dateTimeArgs, 7, TzInfo(datetime.Kind)); + } + var returnDateTime = Runtime.PyObject_CallObject(dateTimeCtor, dateTimeArgs); // clean up Runtime.XDecref(dateTimeArgs);