Skip to content

Commit

Permalink
Do not include timezone if DateTimeKind is Unspecified
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
AlexCatarino committed Aug 23, 2018
1 parent c6db866 commit bec9563
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/runtime/converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit bec9563

Please sign in to comment.