Skip to content

Commit

Permalink
DEPR: enforce Sparse deprecations (pandas-dev#58167)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored Apr 5, 2024
1 parent e8048cd commit cf1be37
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 43 deletions.
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ Removal of prior version deprecations/changes
- All arguments except ``name`` in :meth:`Index.rename` are now keyword only (:issue:`56493`)
- All arguments except the first ``path``-like argument in IO writers are now keyword only (:issue:`54229`)
- Disallow calling :meth:`Series.replace` or :meth:`DataFrame.replace` without a ``value`` and with non-dict-like ``to_replace`` (:issue:`33302`)
- Disallow constructing a :class:`arrays.SparseArray` with scalar data (:issue:`53039`)
- Disallow non-standard (``np.ndarray``, :class:`Index`, :class:`ExtensionArray`, or :class:`Series`) to :func:`isin`, :func:`unique`, :func:`factorize` (:issue:`52986`)
- Disallow passing a pandas type to :meth:`Index.view` (:issue:`55709`)
- Disallow units other than "s", "ms", "us", "ns" for datetime64 and timedelta64 dtypes in :func:`array` (:issue:`53817`)
Expand All @@ -217,6 +218,7 @@ Removal of prior version deprecations/changes
- Removed deprecated "method" and "limit" keywords from :meth:`Series.replace` and :meth:`DataFrame.replace` (:issue:`53492`)
- Removed extension test classes ``BaseNoReduceTests``, ``BaseNumericReduceTests``, ``BaseBooleanReduceTests`` (:issue:`54663`)
- Removed the "closed" and "normalize" keywords in :meth:`DatetimeIndex.__new__` (:issue:`52628`)
- Require :meth:`SparseDtype.fill_value` to be a valid value for the :meth:`SparseDtype.subtype` (:issue:`53043`)
- Stopped performing dtype inference with in :meth:`Index.insert` with object-dtype index; this often affects the index/columns that result when setting new entries into an empty :class:`Series` or :class:`DataFrame` (:issue:`51363`)
- Removed the "closed" and "unit" keywords in :meth:`TimedeltaIndex.__new__` (:issue:`52628`, :issue:`55499`)
- All arguments in :meth:`Index.sort_values` are now keyword only (:issue:`56493`)
Expand Down
16 changes: 3 additions & 13 deletions pandas/core/arrays/sparse/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

from pandas.core.dtypes.astype import astype_array
from pandas.core.dtypes.cast import (
construct_1d_arraylike_from_scalar,
find_common_type,
maybe_box_datetimelike,
)
Expand Down Expand Up @@ -399,19 +398,10 @@ def __init__(
dtype = dtype.subtype

if is_scalar(data):
warnings.warn(
f"Constructing {type(self).__name__} with scalar data is deprecated "
"and will raise in a future version. Pass a sequence instead.",
FutureWarning,
stacklevel=find_stack_level(),
raise TypeError(
f"Cannot construct {type(self).__name__} from scalar data. "
"Pass a sequence instead."
)
if sparse_index is None:
npoints = 1
else:
npoints = sparse_index.length

data = construct_1d_arraylike_from_scalar(data, npoints, dtype=None)
dtype = data.dtype

if dtype is not None:
dtype = pandas_dtype(dtype)
Expand Down
18 changes: 6 additions & 12 deletions pandas/core/dtypes/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1762,24 +1762,18 @@ def _check_fill_value(self) -> None:
val = self._fill_value
if isna(val):
if not is_valid_na_for_dtype(val, self.subtype):
warnings.warn(
"Allowing arbitrary scalar fill_value in SparseDtype is "
"deprecated. In a future version, the fill_value must be "
"a valid value for the SparseDtype.subtype.",
FutureWarning,
stacklevel=find_stack_level(),
raise ValueError(
# GH#53043
"fill_value must be a valid value for the SparseDtype.subtype"
)
else:
dummy = np.empty(0, dtype=self.subtype)
dummy = ensure_wrapped_if_datetimelike(dummy)

if not can_hold_element(dummy, val):
warnings.warn(
"Allowing arbitrary scalar fill_value in SparseDtype is "
"deprecated. In a future version, the fill_value must be "
"a valid value for the SparseDtype.subtype.",
FutureWarning,
stacklevel=find_stack_level(),
raise ValueError(
# GH#53043
"fill_value must be a valid value for the SparseDtype.subtype"
)

@property
Expand Down
10 changes: 6 additions & 4 deletions pandas/tests/arrays/sparse/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ def test_set_fill_value(self):
arr.fill_value = 2
assert arr.fill_value == 2

msg = "Allowing arbitrary scalar fill_value in SparseDtype is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
msg = "fill_value must be a valid value for the SparseDtype.subtype"
with pytest.raises(ValueError, match=msg):
# GH#53043
arr.fill_value = 3.1
assert arr.fill_value == 3.1
assert arr.fill_value == 2

arr.fill_value = np.nan
assert np.isnan(arr.fill_value)
Expand All @@ -64,8 +65,9 @@ def test_set_fill_value(self):
arr.fill_value = True
assert arr.fill_value is True

with tm.assert_produces_warning(FutureWarning, match=msg):
with pytest.raises(ValueError, match=msg):
arr.fill_value = 0
assert arr.fill_value is True

arr.fill_value = np.nan
assert np.isnan(arr.fill_value)
Expand Down
18 changes: 5 additions & 13 deletions pandas/tests/arrays/sparse/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,20 +144,12 @@ def test_constructor_spindex_dtype(self):
@pytest.mark.parametrize("sparse_index", [None, IntIndex(1, [0])])
def test_constructor_spindex_dtype_scalar(self, sparse_index):
# scalar input
msg = "Constructing SparseArray with scalar data is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
arr = SparseArray(data=1, sparse_index=sparse_index, dtype=None)
exp = SparseArray([1], dtype=None)
tm.assert_sp_array_equal(arr, exp)
assert arr.dtype == SparseDtype(np.int64)
assert arr.fill_value == 0
msg = "Cannot construct SparseArray from scalar data. Pass a sequence instead"
with pytest.raises(TypeError, match=msg):
SparseArray(data=1, sparse_index=sparse_index, dtype=None)

with tm.assert_produces_warning(FutureWarning, match=msg):
arr = SparseArray(data=1, sparse_index=IntIndex(1, [0]), dtype=None)
exp = SparseArray([1], dtype=None)
tm.assert_sp_array_equal(arr, exp)
assert arr.dtype == SparseDtype(np.int64)
assert arr.fill_value == 0
with pytest.raises(TypeError, match=msg):
SparseArray(data=1, sparse_index=IntIndex(1, [0]), dtype=None)

def test_constructor_spindex_dtype_scalar_broadcasts(self):
arr = SparseArray(
Expand Down
1 change: 0 additions & 1 deletion pandas/tests/arrays/sparse/test_dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def test_nans_not_equal():
(SparseDtype("float64"), SparseDtype("float32")),
(SparseDtype("float64"), SparseDtype("float64", 0)),
(SparseDtype("float64"), SparseDtype("datetime64[ns]", np.nan)),
(SparseDtype(int, pd.NaT), SparseDtype(float, pd.NaT)),
(SparseDtype("float64"), np.dtype("float64")),
]

Expand Down

0 comments on commit cf1be37

Please sign in to comment.