Skip to content

Commit cf1be37

Browse files
authored
DEPR: enforce Sparse deprecations (#58167)
1 parent e8048cd commit cf1be37

File tree

6 files changed

+22
-43
lines changed

6 files changed

+22
-43
lines changed

doc/source/whatsnew/v3.0.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ Removal of prior version deprecations/changes
208208
- All arguments except ``name`` in :meth:`Index.rename` are now keyword only (:issue:`56493`)
209209
- All arguments except the first ``path``-like argument in IO writers are now keyword only (:issue:`54229`)
210210
- Disallow calling :meth:`Series.replace` or :meth:`DataFrame.replace` without a ``value`` and with non-dict-like ``to_replace`` (:issue:`33302`)
211+
- Disallow constructing a :class:`arrays.SparseArray` with scalar data (:issue:`53039`)
211212
- Disallow non-standard (``np.ndarray``, :class:`Index`, :class:`ExtensionArray`, or :class:`Series`) to :func:`isin`, :func:`unique`, :func:`factorize` (:issue:`52986`)
212213
- Disallow passing a pandas type to :meth:`Index.view` (:issue:`55709`)
213214
- Disallow units other than "s", "ms", "us", "ns" for datetime64 and timedelta64 dtypes in :func:`array` (:issue:`53817`)
@@ -217,6 +218,7 @@ Removal of prior version deprecations/changes
217218
- Removed deprecated "method" and "limit" keywords from :meth:`Series.replace` and :meth:`DataFrame.replace` (:issue:`53492`)
218219
- Removed extension test classes ``BaseNoReduceTests``, ``BaseNumericReduceTests``, ``BaseBooleanReduceTests`` (:issue:`54663`)
219220
- Removed the "closed" and "normalize" keywords in :meth:`DatetimeIndex.__new__` (:issue:`52628`)
221+
- Require :meth:`SparseDtype.fill_value` to be a valid value for the :meth:`SparseDtype.subtype` (:issue:`53043`)
220222
- 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`)
221223
- Removed the "closed" and "unit" keywords in :meth:`TimedeltaIndex.__new__` (:issue:`52628`, :issue:`55499`)
222224
- All arguments in :meth:`Index.sort_values` are now keyword only (:issue:`56493`)

pandas/core/arrays/sparse/array.py

+3-13
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040

4141
from pandas.core.dtypes.astype import astype_array
4242
from pandas.core.dtypes.cast import (
43-
construct_1d_arraylike_from_scalar,
4443
find_common_type,
4544
maybe_box_datetimelike,
4645
)
@@ -399,19 +398,10 @@ def __init__(
399398
dtype = dtype.subtype
400399

401400
if is_scalar(data):
402-
warnings.warn(
403-
f"Constructing {type(self).__name__} with scalar data is deprecated "
404-
"and will raise in a future version. Pass a sequence instead.",
405-
FutureWarning,
406-
stacklevel=find_stack_level(),
401+
raise TypeError(
402+
f"Cannot construct {type(self).__name__} from scalar data. "
403+
"Pass a sequence instead."
407404
)
408-
if sparse_index is None:
409-
npoints = 1
410-
else:
411-
npoints = sparse_index.length
412-
413-
data = construct_1d_arraylike_from_scalar(data, npoints, dtype=None)
414-
dtype = data.dtype
415405

416406
if dtype is not None:
417407
dtype = pandas_dtype(dtype)

pandas/core/dtypes/dtypes.py

+6-12
Original file line numberDiff line numberDiff line change
@@ -1762,24 +1762,18 @@ def _check_fill_value(self) -> None:
17621762
val = self._fill_value
17631763
if isna(val):
17641764
if not is_valid_na_for_dtype(val, self.subtype):
1765-
warnings.warn(
1766-
"Allowing arbitrary scalar fill_value in SparseDtype is "
1767-
"deprecated. In a future version, the fill_value must be "
1768-
"a valid value for the SparseDtype.subtype.",
1769-
FutureWarning,
1770-
stacklevel=find_stack_level(),
1765+
raise ValueError(
1766+
# GH#53043
1767+
"fill_value must be a valid value for the SparseDtype.subtype"
17711768
)
17721769
else:
17731770
dummy = np.empty(0, dtype=self.subtype)
17741771
dummy = ensure_wrapped_if_datetimelike(dummy)
17751772

17761773
if not can_hold_element(dummy, val):
1777-
warnings.warn(
1778-
"Allowing arbitrary scalar fill_value in SparseDtype is "
1779-
"deprecated. In a future version, the fill_value must be "
1780-
"a valid value for the SparseDtype.subtype.",
1781-
FutureWarning,
1782-
stacklevel=find_stack_level(),
1774+
raise ValueError(
1775+
# GH#53043
1776+
"fill_value must be a valid value for the SparseDtype.subtype"
17831777
)
17841778

17851779
@property

pandas/tests/arrays/sparse/test_array.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ def test_set_fill_value(self):
5252
arr.fill_value = 2
5353
assert arr.fill_value == 2
5454

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

6061
arr.fill_value = np.nan
6162
assert np.isnan(arr.fill_value)
@@ -64,8 +65,9 @@ def test_set_fill_value(self):
6465
arr.fill_value = True
6566
assert arr.fill_value is True
6667

67-
with tm.assert_produces_warning(FutureWarning, match=msg):
68+
with pytest.raises(ValueError, match=msg):
6869
arr.fill_value = 0
70+
assert arr.fill_value is True
6971

7072
arr.fill_value = np.nan
7173
assert np.isnan(arr.fill_value)

pandas/tests/arrays/sparse/test_constructors.py

+5-13
Original file line numberDiff line numberDiff line change
@@ -144,20 +144,12 @@ def test_constructor_spindex_dtype(self):
144144
@pytest.mark.parametrize("sparse_index", [None, IntIndex(1, [0])])
145145
def test_constructor_spindex_dtype_scalar(self, sparse_index):
146146
# scalar input
147-
msg = "Constructing SparseArray with scalar data is deprecated"
148-
with tm.assert_produces_warning(FutureWarning, match=msg):
149-
arr = SparseArray(data=1, sparse_index=sparse_index, dtype=None)
150-
exp = SparseArray([1], dtype=None)
151-
tm.assert_sp_array_equal(arr, exp)
152-
assert arr.dtype == SparseDtype(np.int64)
153-
assert arr.fill_value == 0
147+
msg = "Cannot construct SparseArray from scalar data. Pass a sequence instead"
148+
with pytest.raises(TypeError, match=msg):
149+
SparseArray(data=1, sparse_index=sparse_index, dtype=None)
154150

155-
with tm.assert_produces_warning(FutureWarning, match=msg):
156-
arr = SparseArray(data=1, sparse_index=IntIndex(1, [0]), dtype=None)
157-
exp = SparseArray([1], dtype=None)
158-
tm.assert_sp_array_equal(arr, exp)
159-
assert arr.dtype == SparseDtype(np.int64)
160-
assert arr.fill_value == 0
151+
with pytest.raises(TypeError, match=msg):
152+
SparseArray(data=1, sparse_index=IntIndex(1, [0]), dtype=None)
161153

162154
def test_constructor_spindex_dtype_scalar_broadcasts(self):
163155
arr = SparseArray(

pandas/tests/arrays/sparse/test_dtype.py

-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ def test_nans_not_equal():
8484
(SparseDtype("float64"), SparseDtype("float32")),
8585
(SparseDtype("float64"), SparseDtype("float64", 0)),
8686
(SparseDtype("float64"), SparseDtype("datetime64[ns]", np.nan)),
87-
(SparseDtype(int, pd.NaT), SparseDtype(float, pd.NaT)),
8887
(SparseDtype("float64"), np.dtype("float64")),
8988
]
9089

0 commit comments

Comments
 (0)