diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 59b164c156d79..92fadf801cec7 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -608,6 +608,7 @@ Missing ^^^^^^^ - Bug in :meth:`DataFrame.fillna` with limit and no method ignores axis='columns' or ``axis = 1`` (:issue:`40989`) - Bug in :meth:`DataFrame.fillna` not replacing missing values when using a dict-like ``value`` and duplicate column names (:issue:`43476`) +- Bug in constructing a :class:`DataFrame` with a dictionary ``np.datetime64`` as a value and ``dtype='timedelta64[ns]'``, or vice-versa, incorrectly casting instead of raising (:issue:`??`) - MultiIndex diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index e6d6b561803d6..a766f8321a641 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -443,15 +443,18 @@ def dict_to_mgr( if missing.any() and not is_integer_dtype(dtype): nan_dtype: DtypeObj - if dtype is None or ( - isinstance(dtype, np.dtype) and np.issubdtype(dtype, np.flexible) - ): + if dtype is not None: + # calling sanitize_array ensures we don't mix-and-match + # NA dtypes + midxs = missing.values.nonzero()[0] + for i in midxs: + arr = sanitize_array(arrays.iat[i], index, dtype=dtype) + arrays.iat[i] = arr + else: # GH#1783 nan_dtype = np.dtype("object") - else: - nan_dtype = dtype - val = construct_1d_arraylike_from_scalar(np.nan, len(index), nan_dtype) - arrays.loc[missing] = [val] * missing.sum() + val = construct_1d_arraylike_from_scalar(np.nan, len(index), nan_dtype) + arrays.loc[missing] = [val] * missing.sum() arrays = list(arrays) columns = ensure_index(columns) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index f92bbe1c718ab..52797862afa14 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -2903,14 +2903,7 @@ def test_from_timedelta64_scalar_object(self, constructor): assert isinstance(get1(obj), np.timedelta64) @pytest.mark.parametrize("cls", [np.datetime64, np.timedelta64]) - def test_from_scalar_datetimelike_mismatched(self, constructor, cls, request): - node = request.node - params = node.callspec.params - if params["frame_or_series"] is DataFrame and params["constructor"] is dict: - mark = pytest.mark.xfail( - reason="DataFrame incorrectly allows mismatched datetimelike" - ) - node.add_marker(mark) + def test_from_scalar_datetimelike_mismatched(self, constructor, cls): scalar = cls("NaT", "ns") dtype = {np.datetime64: "m8[ns]", np.timedelta64: "M8[ns]"}[cls]