Skip to content

Commit 2bacb4b

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 9e75794 commit 2bacb4b

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
@@ -293,15 +293,27 @@ internal static IntPtr ToPython(object value, Type type)
293293
case TypeCode.DateTime:
294294
var datetime = (DateTime)value;
295295

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

0 commit comments

Comments
 (0)