diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 2e1ebf9d5a266..a8cc07c8fd964 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -1466,8 +1466,6 @@ def max(self, *, axis: int | None = None, skipna: bool = True, **kwargs): Index.max : Return the maximum value in an Index. Series.max : Return the maximum value in a Series. """ - # TODO: skipna is broken with max. - # See https://github.com/pandas-dev/pandas/issues/24265 nv.validate_max((), kwargs) nv.validate_minmax_axis(axis, self.ndim) diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index 568f3484e78e4..34aaf054de48e 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -605,7 +605,7 @@ def value_counts(self, dropna: bool = True) -> Series: data = self._data[~self._mask] value_counts = Index(data).value_counts() - # TODO(extension) + # TODO(ExtensionIndex) # if we have allow Index to hold an ExtensionArray # this is easier index = value_counts.index._values.astype(object) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index b8354e800753d..4535010b29c3a 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -1039,7 +1039,7 @@ def _wrap_applied_output_series( key_index, ) -> DataFrame | Series: # this is to silence a DeprecationWarning - # TODO: Remove when default dtype of empty Series is object + # TODO(2.0): Remove when default dtype of empty Series is object kwargs = first_not_none._construct_axes_dict() backup = create_series_with_explicit_dtype(dtype_if_empty=object, **kwargs) values = [x if (x is not None) else backup for x in values] diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 00c4d2778e545..97f5ef20c5c5e 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -3337,7 +3337,8 @@ def pct_change(self, periods=1, fill_method="pad", limit=None, freq=None, axis=0 Series or DataFrame Percentage changes within each group. """ - # TODO: Remove this conditional for SeriesGroupBy when GH#23918 is fixed + # TODO(GH#23918): Remove this conditional for SeriesGroupBy when + # GH#23918 is fixed if freq is not None or axis != 0: return self.apply( lambda x: x.pct_change( diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py index 60c8851f059fe..8223a04883738 100644 --- a/pandas/core/groupby/ops.py +++ b/pandas/core/groupby/ops.py @@ -868,8 +868,8 @@ def result_arraylike(self) -> ArrayLike: Analogous to result_index, but returning an ndarray/ExtensionArray allowing us to retain ExtensionDtypes not supported by Index. """ - # TODO: once Index supports arbitrary EAs, this can be removed in favor - # of result_index + # TODO(ExtensionIndex): once Index supports arbitrary EAs, this can + # be removed in favor of result_index if len(self.groupings) == 1: return self.groupings[0].group_arraylike diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index e77cdd7ad7369..74d785586b950 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -80,8 +80,6 @@ operate_blockwise, ) -# TODO: flexible with index=None and/or items=None - T = TypeVar("T", bound="BaseBlockManager") diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index a95592c96d411..10d95dfbb9181 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1781,16 +1781,20 @@ def na_accum_func(values: ArrayLike, accum_func, *, skipna: bool) -> ArrayLike: # We need to define mask before masking NaTs mask = isna(values) - if accum_func == np.minimum.accumulate: - # Note: the accum_func comparison fails as an "is" comparison - y = values.view("i8") - y[mask] = lib.i8max - changed = True - else: - y = values - changed = False + y = values.view("i8") + # Note: the accum_func comparison fails as an "is" comparison + changed = accum_func == np.minimum.accumulate + + try: + if changed: + y[mask] = lib.i8max + + result = accum_func(y, axis=0) + finally: + if changed: + # restore NaT elements + y[mask] = iNaT - result = accum_func(y.view("i8"), axis=0) if skipna: result[mask] = iNaT elif accum_func == np.minimum.accumulate: @@ -1800,10 +1804,6 @@ def na_accum_func(values: ArrayLike, accum_func, *, skipna: bool) -> ArrayLike: # everything up to the first non-na entry stays NaT result[: nz[0]] = iNaT - if changed: - # restore NaT elements - y[mask] = iNaT # TODO: could try/finally for this? - if isinstance(values.dtype, np.dtype): result = result.view(orig_dtype) else: diff --git a/pandas/io/sas/sas7bdat.py b/pandas/io/sas/sas7bdat.py index 300df9728cd75..38b42f4470058 100644 --- a/pandas/io/sas/sas7bdat.py +++ b/pandas/io/sas/sas7bdat.py @@ -103,13 +103,14 @@ class _Column: col_id: int name: str | bytes label: str | bytes - format: str | bytes # TODO: i think allowing bytes is from py2 days + format: str | bytes ctype: bytes length: int def __init__( self, col_id: int, + # These can be bytes when convert_header_text is False name: str | bytes, label: str | bytes, format: str | bytes, diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 75cabf1681bc7..4be54ceaa2bcf 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -2158,9 +2158,6 @@ def to_sql( table.insert(chunksize, method) def has_table(self, name: str, schema: str | None = None): - # TODO(wesm): unused? - # escape = _get_valid_sqlite_name - # esc_name = escape(name) wld = "?" query = f"SELECT name FROM sqlite_master WHERE type='table' AND name={wld};" diff --git a/pandas/tests/apply/test_series_apply.py b/pandas/tests/apply/test_series_apply.py index 1d0b64c1835df..b7084e2bc6dc7 100644 --- a/pandas/tests/apply/test_series_apply.py +++ b/pandas/tests/apply/test_series_apply.py @@ -794,18 +794,15 @@ def test_apply_to_timedelta(): list_of_valid_strings = ["00:00:01", "00:00:02"] a = pd.to_timedelta(list_of_valid_strings) b = Series(list_of_valid_strings).apply(pd.to_timedelta) - # FIXME: dont leave commented-out - # Can't compare until apply on a Series gives the correct dtype - # assert_series_equal(a, b) + tm.assert_series_equal(Series(a), b) list_of_strings = ["00:00:01", np.nan, pd.NaT, pd.NaT] - a = pd.to_timedelta(list_of_strings) # noqa + a = pd.to_timedelta(list_of_strings) with tm.assert_produces_warning(FutureWarning, match="Inferring timedelta64"): ser = Series(list_of_strings) - b = ser.apply(pd.to_timedelta) # noqa - # Can't compare until apply on a Series gives the correct dtype - # assert_series_equal(a, b) + b = ser.apply(pd.to_timedelta) + tm.assert_series_equal(Series(a), b) @pytest.mark.parametrize( diff --git a/pandas/tests/arrays/floating/test_arithmetic.py b/pandas/tests/arrays/floating/test_arithmetic.py index e674b49a99bd4..5d959b9224e52 100644 --- a/pandas/tests/arrays/floating/test_arithmetic.py +++ b/pandas/tests/arrays/floating/test_arithmetic.py @@ -142,17 +142,16 @@ def test_error_invalid_values(data, all_arithmetic_operators): with pytest.raises(TypeError, match=msg): ops(pd.Series("foo", index=s.index)) - if op != "__rpow__": - # TODO(extension) - # rpow with a datetimelike coerces the integer array incorrectly - msg = ( - "can only perform ops with numeric values|" - "cannot perform .* with this index type: DatetimeArray|" + msg = "|".join( + [ + "can only perform ops with numeric values", + "cannot perform .* with this index type: DatetimeArray", "Addition/subtraction of integers and integer-arrays " - "with DatetimeArray is no longer supported. *" - ) - with pytest.raises(TypeError, match=msg): - ops(pd.Series(pd.date_range("20180101", periods=len(s)))) + "with DatetimeArray is no longer supported. *", + ] + ) + with pytest.raises(TypeError, match=msg): + ops(pd.Series(pd.date_range("20180101", periods=len(s)))) # Various diff --git a/pandas/tests/arrays/integer/test_arithmetic.py b/pandas/tests/arrays/integer/test_arithmetic.py index 4f66e2ecfd355..5a5d047996747 100644 --- a/pandas/tests/arrays/integer/test_arithmetic.py +++ b/pandas/tests/arrays/integer/test_arithmetic.py @@ -179,17 +179,16 @@ def test_error_invalid_values(data, all_arithmetic_operators): with pytest.raises(TypeError, match=msg): ops(pd.Series("foo", index=s.index)) - if op != "__rpow__": - # TODO(extension) - # rpow with a datetimelike coerces the integer array incorrectly - msg = ( - "can only perform ops with numeric values|" - "cannot perform .* with this index type: DatetimeArray|" + msg = "|".join( + [ + "can only perform ops with numeric values", + "cannot perform .* with this index type: DatetimeArray", "Addition/subtraction of integers and integer-arrays " - "with DatetimeArray is no longer supported. *" - ) - with pytest.raises(TypeError, match=msg): - ops(pd.Series(pd.date_range("20180101", periods=len(s)))) + "with DatetimeArray is no longer supported. *", + ] + ) + with pytest.raises(TypeError, match=msg): + ops(pd.Series(pd.date_range("20180101", periods=len(s)))) # Various diff --git a/pandas/tests/arrays/test_datetimes.py b/pandas/tests/arrays/test_datetimes.py index 5b9df44f5b565..0453b1ef1c40d 100644 --- a/pandas/tests/arrays/test_datetimes.py +++ b/pandas/tests/arrays/test_datetimes.py @@ -33,9 +33,13 @@ def test_cmp_dt64_arraylike_tznaive(self, comparison_op): result = op(arr, arr) tm.assert_numpy_array_equal(result, expected) - for other in [right, np.array(right)]: - # TODO: add list and tuple, and object-dtype once those - # are fixed in the constructor + for other in [ + right, + np.array(right), + list(right), + tuple(right), + right.astype(object), + ]: result = op(arr, other) tm.assert_numpy_array_equal(result, expected) diff --git a/pandas/tests/frame/test_arithmetic.py b/pandas/tests/frame/test_arithmetic.py index 1ddb18c218cc6..6927a5927ef48 100644 --- a/pandas/tests/frame/test_arithmetic.py +++ b/pandas/tests/frame/test_arithmetic.py @@ -925,8 +925,8 @@ def test_binop_other(self, op, value, dtype, switch_numexpr_min_elements): (operator.mul, "bool"), } - e = DummyElement(value, dtype) - s = DataFrame({"A": [e.value, e.value]}, dtype=e.dtype) + elem = DummyElement(value, dtype) + df = DataFrame({"A": [elem.value, elem.value]}, dtype=elem.dtype) invalid = { (operator.pow, "