Skip to content
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ Indexing
- Bug in :meth:`DataFrame.__getitem__` and :meth:`Series.__getitem__` always raising ``KeyError`` when slicing with existing strings an :class:`Index` with milliseconds (:issue:`33589`)
- Bug in setting ``timedelta64`` values into numeric :class:`Series` failing to cast to object dtype (:issue:`39086`)
- Bug in setting :class:`Interval` values into a :class:`Series` or :class:`DataFrame` with mismatched :class:`IntervalDtype` incorrectly casting the new values to the existing dtype (:issue:`39120`)
- Bug in setting ``datetime64`` values into a :class:`Series` with integer-dtype incorrect casting the datetime64 values to integers (:issue:`39266`)
- Bug in incorrectly raising in :meth:`Index.insert`, when setting a new column that cannot be held in the existing ``frame.columns``, or in :meth:`Series.reset_index` or :meth:`DataFrame.reset_index` instead of casting to a compatible dtype (:issue:`39068`)

Missing
Expand Down
12 changes: 11 additions & 1 deletion pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,8 +968,18 @@ def setitem(self, indexer, value):
# TODO(EA2D): special case not needed with 2D EA
values[indexer] = value.to_numpy(values.dtype).reshape(-1, 1)

# set
elif self.is_object and not is_ea_value and arr_value.dtype.kind in ["m", "M"]:
# https://github.com/numpy/numpy/issues/12550
# numpy will incorrect cast to int if we're not careful
if is_list_like(value):
value = list(value)
else:
value = [value] * len(values[indexer])

values[indexer] = value

else:

values[indexer] = value

if transpose:
Expand Down
21 changes: 21 additions & 0 deletions pandas/tests/series/indexing/test_setitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,27 @@ def test_setitem_callable_other(self):
tm.assert_series_equal(ser, expected)


class TestSetitemCasting:
@pytest.mark.parametrize("dtype", ["M8[ns]", "m8[ns]"])
def test_setitem_dt64_into_int_series(self, dtype):
# dont cast dt64 to int when doing this setitem
orig = Series([1, 2, 3])

val = np.datetime64("2021-01-18 13:25:00", "ns")
if dtype == "m8[ns]":
val = val - val

ser = orig.copy()
ser[:-1] = val
expected = Series([val, val, 3], dtype=object)
tm.assert_series_equal(ser, expected)
assert isinstance(ser[0], type(val))

ser = orig.copy()
ser[:-1] = np.array([val, val])
tm.assert_series_equal(ser, expected)


@pytest.mark.parametrize(
"obj,expected,key",
[
Expand Down