Skip to content

Commit bec9563

Browse files
committed
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.
1 parent c6db866 commit bec9563

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/runtime/converter.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,15 +292,27 @@ internal static IntPtr ToPython(object value, Type type)
292292
case TypeCode.DateTime:
293293
var datetime = (DateTime)value;
294294

295-
IntPtr dateTimeArgs = Runtime.PyTuple_New(8);
295+
var size = datetime.Kind == DateTimeKind.Unspecified ? 7 : 8;
296+
297+
IntPtr dateTimeArgs = Runtime.PyTuple_New(size);
296298
Runtime.PyTuple_SetItem(dateTimeArgs, 0, Runtime.PyInt_FromInt32(datetime.Year));
297299
Runtime.PyTuple_SetItem(dateTimeArgs, 1, Runtime.PyInt_FromInt32(datetime.Month));
298300
Runtime.PyTuple_SetItem(dateTimeArgs, 2, Runtime.PyInt_FromInt32(datetime.Day));
299301
Runtime.PyTuple_SetItem(dateTimeArgs, 3, Runtime.PyInt_FromInt32(datetime.Hour));
300302
Runtime.PyTuple_SetItem(dateTimeArgs, 4, Runtime.PyInt_FromInt32(datetime.Minute));
301303
Runtime.PyTuple_SetItem(dateTimeArgs, 5, Runtime.PyInt_FromInt32(datetime.Second));
302-
Runtime.PyTuple_SetItem(dateTimeArgs, 6, Runtime.PyInt_FromInt32(datetime.Millisecond));
303-
Runtime.PyTuple_SetItem(dateTimeArgs, 7, TzInfo(datetime.Kind));
304+
305+
// datetime.datetime 6th argument represents micro seconds
306+
var totalSeconds = datetime.TimeOfDay.TotalSeconds;
307+
var microSeconds = Convert.ToInt32((totalSeconds - Math.Truncate(totalSeconds)) * 1000000);
308+
if (microSeconds == 1000000) microSeconds = 999999;
309+
Runtime.PyTuple_SetItem(dateTimeArgs, 6, Runtime.PyInt_FromInt32(microSeconds));
310+
311+
if (size == 8)
312+
{
313+
Runtime.PyTuple_SetItem(dateTimeArgs, 7, TzInfo(datetime.Kind));
314+
}
315+
304316
var returnDateTime = Runtime.PyObject_CallObject(dateTimeCtor, dateTimeArgs);
305317
// clean up
306318
Runtime.XDecref(dateTimeArgs);

0 commit comments

Comments
 (0)