diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index abcc60a15c641..8c795c2aad224 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -674,7 +674,7 @@ def infer_dtype_from(val, pandas_dtype: bool = False) -> Tuple[DtypeObj, Any]: If False, scalar/array belongs to pandas extension types is inferred as object """ - if is_scalar(val): + if not is_list_like(val): return infer_dtype_from_scalar(val, pandas_dtype=pandas_dtype) return infer_dtype_from_array(val, pandas_dtype=pandas_dtype) @@ -815,7 +815,7 @@ def infer_dtype_from_array( return arr.dtype, arr if not is_list_like(arr): - arr = [arr] + raise TypeError("'arr' must be list-like") if pandas_dtype and is_extension_array_dtype(arr): return arr.dtype, arr diff --git a/pandas/core/missing.py b/pandas/core/missing.py index 445c1efae22e4..1120416eebeb9 100644 --- a/pandas/core/missing.py +++ b/pandas/core/missing.py @@ -10,7 +10,7 @@ from pandas._typing import ArrayLike, Axis, DtypeObj from pandas.compat._optional import import_optional_dependency -from pandas.core.dtypes.cast import infer_dtype_from_array +from pandas.core.dtypes.cast import infer_dtype_from from pandas.core.dtypes.common import ( ensure_float64, is_integer_dtype, @@ -40,7 +40,7 @@ def mask_missing(arr: ArrayLike, values_to_mask) -> np.ndarray: # When called from Block.replace/replace_list, values_to_mask is a scalar # known to be holdable by arr. # When called from Series._single_replace, values_to_mask is tuple or list - dtype, values_to_mask = infer_dtype_from_array(values_to_mask) + dtype, values_to_mask = infer_dtype_from(values_to_mask) values_to_mask = np.array(values_to_mask, dtype=dtype) na_mask = isna(values_to_mask) diff --git a/pandas/tests/dtypes/cast/test_infer_dtype.py b/pandas/tests/dtypes/cast/test_infer_dtype.py index 16fb6f327a4d5..eaf00718f4c91 100644 --- a/pandas/tests/dtypes/cast/test_infer_dtype.py +++ b/pandas/tests/dtypes/cast/test_infer_dtype.py @@ -141,12 +141,29 @@ def test_infer_dtype_from_scalar_errors(): @pytest.mark.parametrize( - "arr, expected, pandas_dtype", + "value, expected, pandas_dtype", [ ("foo", np.object_, False), (b"foo", np.object_, False), - (1, np.int_, False), + (1, np.int64, False), (1.5, np.float_, False), + (np.datetime64("2016-01-01"), np.dtype("M8[ns]"), False), + (Timestamp("20160101"), np.dtype("M8[ns]"), False), + (Timestamp("20160101", tz="UTC"), np.object_, False), + (Timestamp("20160101", tz="UTC"), "datetime64[ns, UTC]", True), + ], +) +def test_infer_dtype_from_scalar(value, expected, pandas_dtype): + dtype, _ = infer_dtype_from_scalar(value, pandas_dtype=pandas_dtype) + assert is_dtype_equal(dtype, expected) + + with pytest.raises(TypeError, match="must be list-like"): + infer_dtype_from_array(value, pandas_dtype=pandas_dtype) + + +@pytest.mark.parametrize( + "arr, expected, pandas_dtype", + [ ([1], np.int_, False), (np.array([1], dtype=np.int64), np.int64, False), ([np.nan, 1, ""], np.object_, False), @@ -155,8 +172,6 @@ def test_infer_dtype_from_scalar_errors(): (Categorical([1, 2, 3]), np.int64, False), (Categorical(list("aabc")), "category", True), (Categorical([1, 2, 3]), "category", True), - (Timestamp("20160101"), np.object_, False), - (np.datetime64("2016-01-01"), np.dtype("=M8[D]"), False), (date_range("20160101", periods=3), np.dtype("=M8[ns]"), False), ( date_range("20160101", periods=3, tz="US/Eastern"),