diff --git a/pandas/core/arrays/_mixins.py b/pandas/core/arrays/_mixins.py index cf9820c3aa8f8..848e724949bc5 100644 --- a/pandas/core/arrays/_mixins.py +++ b/pandas/core/arrays/_mixins.py @@ -197,8 +197,8 @@ def shift(self, periods=1, fill_value=None, axis=0): return self._from_backing_data(new_values) def _validate_shift_value(self, fill_value): - # TODO: after deprecation in datetimelikearraymixin is enforced, - # we can remove this and ust validate_fill_value directly + # TODO(2.0): after deprecation in datetimelikearraymixin is enforced, + # we can remove this and use validate_fill_value directly return self._validate_scalar(fill_value) def __setitem__(self, key, value): diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 35e2dd25678e5..107cefdf31188 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -524,7 +524,6 @@ def astype(self, dtype: AstypeArg, copy: bool = True) -> ArrayLike: self = self.copy() if copy else self result = self._set_dtype(dtype) - # TODO: consolidate with ndarray case? elif isinstance(dtype, ExtensionDtype): return super().astype(dtype, copy=copy) diff --git a/pandas/core/arrays/sparse/dtype.py b/pandas/core/arrays/sparse/dtype.py index 6684e559b6f88..915e13bc3bbb2 100644 --- a/pandas/core/arrays/sparse/dtype.py +++ b/pandas/core/arrays/sparse/dtype.py @@ -371,7 +371,7 @@ def _subtype_with_str(self): def _get_common_dtype(self, dtypes: list[DtypeObj]) -> DtypeObj | None: # TODO for now only handle SparseDtypes and numpy dtypes => extend - # with other compatibtle extension dtypes + # with other compatible extension dtypes if any( isinstance(x, ExtensionDtype) and not isinstance(x, SparseDtype) for x in dtypes diff --git a/pandas/core/computation/expr.py b/pandas/core/computation/expr.py index 51af2cd732d09..f8716ca1bafe0 100644 --- a/pandas/core/computation/expr.py +++ b/pandas/core/computation/expr.py @@ -253,7 +253,6 @@ def _filter_nodes(superclass, all_nodes=_all_nodes): assert not intersection, _msg -# TODO: Python 3.6.2: replace Callable[..., None] with Callable[..., NoReturn] def _node_not_implemented(node_name: str) -> Callable[..., None]: """ Return a function that raises a NotImplementedError with a passed node name. diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 5afb19f1d91fe..2488048e30ccb 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -5356,7 +5356,6 @@ def _replace_columnwise( """ Dispatch to Series.replace column-wise. - Parameters ---------- mapping : dict diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 6895455a43160..8b2774fd0f1b3 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4974,7 +4974,7 @@ def _reindex_with_indexers( if indexer is not None: indexer = ensure_platform_int(indexer) - # TODO: speed up on homogeneous DataFrame objects + # TODO: speed up on homogeneous DataFrame objects (see _reindex_multi) new_data = new_data.reindex_indexer( index, indexer, @@ -6420,7 +6420,7 @@ def fillna( ) elif isinstance(value, ABCDataFrame) and self.ndim == 2: - new_data = self.where(self.notna(), value)._data + new_data = self.where(self.notna(), value)._mgr else: raise ValueError(f"invalid fill value with a {type(value)}") diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 8a2ba69a61ed9..77281441c2ed2 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -1797,7 +1797,7 @@ def count(self) -> Series | DataFrame: is_series = data.ndim == 1 def hfunc(bvalues: ArrayLike) -> ArrayLike: - # TODO(2DEA): reshape would not be necessary with 2D EAs + # TODO(EA2D): reshape would not be necessary with 2D EAs if bvalues.ndim == 1: # EA masked = mask & ~isna(bvalues).reshape(1, -1) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 7e533233d5ecf..bc9f5c3243705 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -917,7 +917,7 @@ def setitem(self, indexer, value): value = np.nan # coerce if block dtype can store value - values = self.values + values = cast(np.ndarray, self.values) if not self._can_hold_element(value): # current dtype cannot store value, coerce to common dtype return self.coerce_to_target_dtype(value).setitem(indexer, value) @@ -946,11 +946,7 @@ def setitem(self, indexer, value): values[indexer] = value else: - # error: Argument 1 to "setitem_datetimelike_compat" has incompatible type - # "Union[ndarray, ExtensionArray]"; expected "ndarray" - value = setitem_datetimelike_compat( - values, len(values[indexer]), value # type: ignore[arg-type] - ) + value = setitem_datetimelike_compat(values, len(values[indexer]), value) values[indexer] = value if transpose: @@ -1729,8 +1725,7 @@ def is_view(self) -> bool: def setitem(self, indexer, value): if not self._can_hold_element(value): - # TODO: general case needs casting logic. - return self.astype(_dtype_obj).setitem(indexer, value) + return self.coerce_to_target_dtype(value).setitem(indexer, value) values = self.values if self.ndim > 1: @@ -1751,7 +1746,6 @@ def putmask(self, mask, new) -> list[Block]: return [self] def where(self, other, cond, errors="raise") -> list[Block]: - # TODO(EA2D): reshape unnecessary with 2D EAs arr = self.values cond = extract_bool_array(cond) diff --git a/pandas/core/series.py b/pandas/core/series.py index 9795e1f7141ee..65592be32b5ef 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -4528,6 +4528,9 @@ def rename( 5 3 dtype: int64 """ + if axis is not None: + axis = self._get_axis_number(axis) + if callable(index) or is_dict_like(index): return super().rename( index, copy=copy, inplace=inplace, level=level, errors=errors diff --git a/pandas/tests/arithmetic/common.py b/pandas/tests/arithmetic/common.py index 649ad562307c0..6f4e35ad4dfb2 100644 --- a/pandas/tests/arithmetic/common.py +++ b/pandas/tests/arithmetic/common.py @@ -34,9 +34,18 @@ def assert_invalid_addsub_type(left, right, msg=None): right - left +def get_expected_box(box): + """ + Get the box to use for 'expected' in a comparison operation. + """ + if box in [Index, array]: + return np.ndarray + return box + + def get_upcast_box(box, vector): """ - Given two box-types, find the one that takes priority + Given two box-types, find the one that takes priority. """ if box is DataFrame or isinstance(vector, DataFrame): return DataFrame diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py index 0d3f7dcaaf65b..e511c1bdaca9c 100644 --- a/pandas/tests/arithmetic/test_datetime64.py +++ b/pandas/tests/arithmetic/test_datetime64.py @@ -43,6 +43,7 @@ from pandas.tests.arithmetic.common import ( assert_invalid_addsub_type, assert_invalid_comparison, + get_expected_box, get_upcast_box, ) @@ -59,9 +60,7 @@ def test_compare_zerodim(self, tz_naive_fixture, box_with_array): # Test comparison with zero-dimensional array is unboxed tz = tz_naive_fixture box = box_with_array - xbox = ( - box_with_array if box_with_array not in [pd.Index, pd.array] else np.ndarray - ) + xbox = get_expected_box(box) dti = date_range("20130101", periods=3, tz=tz) other = np.array(dti.to_numpy()[0]) @@ -148,7 +147,7 @@ def test_dt64arr_nat_comparison(self, tz_naive_fixture, box_with_array): # GH#22242, GH#22163 DataFrame considered NaT == ts incorrectly tz = tz_naive_fixture box = box_with_array - xbox = box if box not in [pd.Index, pd.array] else np.ndarray + xbox = get_expected_box(box) ts = Timestamp.now(tz) ser = Series([ts, NaT]) @@ -245,7 +244,7 @@ def test_nat_comparisons_scalar(self, dtype, data, box_with_array): # on older numpys (since they check object identity) return - xbox = box if box not in [pd.Index, pd.array] else np.ndarray + xbox = get_expected_box(box) left = Series(data, dtype=dtype) left = tm.box_expected(left, box) @@ -324,9 +323,7 @@ def test_timestamp_compare_series(self, left, right): def test_dt64arr_timestamp_equality(self, box_with_array): # GH#11034 - xbox = ( - box_with_array if box_with_array not in [pd.Index, pd.array] else np.ndarray - ) + xbox = get_expected_box(box_with_array) ser = Series([Timestamp("2000-01-29 01:59:00"), Timestamp("2000-01-30"), NaT]) ser = tm.box_expected(ser, box_with_array) @@ -424,9 +421,7 @@ def test_dti_cmp_nat(self, dtype, box_with_array): # on older numpys (since they check object identity) return - xbox = ( - box_with_array if box_with_array not in [pd.Index, pd.array] else np.ndarray - ) + xbox = get_expected_box(box_with_array) left = DatetimeIndex([Timestamp("2011-01-01"), NaT, Timestamp("2011-01-03")]) right = DatetimeIndex([NaT, NaT, Timestamp("2011-01-03")]) @@ -662,7 +657,7 @@ def test_scalar_comparison_tzawareness( box = box_with_array tz = tz_aware_fixture dti = date_range("2016-01-01", periods=2, tz=tz) - xbox = box if box not in [pd.Index, pd.array] else np.ndarray + xbox = get_expected_box(box) dtarr = tm.box_expected(dti, box_with_array) if op in [operator.eq, operator.ne]: @@ -2283,7 +2278,7 @@ def test_sub_dti_dti(self): # cleanup, box-parametrization, and de-duplication @pytest.mark.parametrize("op", [operator.add, operator.sub]) - def test_timedelta64_equal_timedelta_supported_ops(self, op): + def test_timedelta64_equal_timedelta_supported_ops(self, op, box_with_array): ser = Series( [ Timestamp("20130301"), @@ -2292,6 +2287,7 @@ def test_timedelta64_equal_timedelta_supported_ops(self, op): Timestamp("20130228 21:00:00"), ] ) + obj = box_with_array(ser) intervals = ["D", "h", "m", "s", "us"] @@ -2302,10 +2298,10 @@ def timedelta64(*args): for d, h, m, s, us in product(*([range(2)] * 5)): nptd = timedelta64(d, h, m, s, us) pytd = timedelta(days=d, hours=h, minutes=m, seconds=s, microseconds=us) - lhs = op(ser, nptd) - rhs = op(ser, pytd) + lhs = op(obj, nptd) + rhs = op(obj, pytd) - tm.assert_series_equal(lhs, rhs) + tm.assert_equal(lhs, rhs) def test_ops_nat_mixed_datetime64_timedelta64(self): # GH#11349 diff --git a/pandas/tests/arithmetic/test_period.py b/pandas/tests/arithmetic/test_period.py index 7d215c940c031..0c42be517b798 100644 --- a/pandas/tests/arithmetic/test_period.py +++ b/pandas/tests/arithmetic/test_period.py @@ -25,7 +25,10 @@ import pandas._testing as tm from pandas.core import ops from pandas.core.arrays import TimedeltaArray -from pandas.tests.arithmetic.common import assert_invalid_comparison +from pandas.tests.arithmetic.common import ( + assert_invalid_comparison, + get_expected_box, +) # ------------------------------------------------------------------ # Comparisons @@ -38,9 +41,7 @@ class TestPeriodArrayLikeComparisons: def test_compare_zerodim(self, box_with_array): # GH#26689 make sure we unbox zero-dimensional arrays - xbox = ( - box_with_array if box_with_array not in [pd.Index, pd.array] else np.ndarray - ) + xbox = get_expected_box(box_with_array) pi = period_range("2000", periods=4) other = np.array(pi.to_numpy()[0]) @@ -77,11 +78,10 @@ def test_compare_invalid_listlike(self, box_with_array, other): @pytest.mark.parametrize("other_box", [list, np.array, lambda x: x.astype(object)]) def test_compare_object_dtype(self, box_with_array, other_box): + xbox = get_expected_box(box_with_array) pi = period_range("2000", periods=5) parr = tm.box_expected(pi, box_with_array) - xbox = np.ndarray if box_with_array in [pd.Index, pd.array] else box_with_array - other = other_box(pi) expected = np.array([True, True, True, True, True]) @@ -187,9 +187,7 @@ def test_pi_cmp_period(self): # TODO: moved from test_datetime64; de-duplicate with version below def test_parr_cmp_period_scalar2(self, box_with_array): - xbox = ( - box_with_array if box_with_array not in [pd.Index, pd.array] else np.ndarray - ) + xbox = get_expected_box(box_with_array) pi = period_range("2000-01-01", periods=10, freq="D") @@ -210,7 +208,7 @@ def test_parr_cmp_period_scalar2(self, box_with_array): @pytest.mark.parametrize("freq", ["M", "2M", "3M"]) def test_parr_cmp_period_scalar(self, freq, box_with_array): # GH#13200 - xbox = np.ndarray if box_with_array in [pd.Index, pd.array] else box_with_array + xbox = get_expected_box(box_with_array) base = PeriodIndex(["2011-01", "2011-02", "2011-03", "2011-04"], freq=freq) base = tm.box_expected(base, box_with_array) @@ -249,7 +247,7 @@ def test_parr_cmp_period_scalar(self, freq, box_with_array): @pytest.mark.parametrize("freq", ["M", "2M", "3M"]) def test_parr_cmp_pi(self, freq, box_with_array): # GH#13200 - xbox = np.ndarray if box_with_array in [pd.Index, pd.array] else box_with_array + xbox = get_expected_box(box_with_array) base = PeriodIndex(["2011-01", "2011-02", "2011-03", "2011-04"], freq=freq) base = tm.box_expected(base, box_with_array) diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py index a2b7d93884a4e..7765c29ee59c8 100644 --- a/pandas/tests/arithmetic/test_timedelta64.py +++ b/pandas/tests/arithmetic/test_timedelta64.py @@ -1198,7 +1198,7 @@ def test_td64arr_addsub_integer_array_no_freq(self, box_with_array): # ------------------------------------------------------------------ # Operations with timedelta-like others - def test_td64arr_add_td64_array(self, box_with_array): + def test_td64arr_add_sub_td64_array(self, box_with_array): box = box_with_array dti = pd.date_range("2016-01-01", periods=3) tdi = dti - dti.shift(1) @@ -1213,20 +1213,11 @@ def test_td64arr_add_td64_array(self, box_with_array): result = tdarr + tdi tm.assert_equal(result, expected) - def test_td64arr_sub_td64_array(self, box_with_array): - box = box_with_array - dti = pd.date_range("2016-01-01", periods=3) - tdi = dti - dti.shift(1) - tdarr = tdi.values - - expected = 0 * tdi - tdi = tm.box_expected(tdi, box) - expected = tm.box_expected(expected, box) - + expected_sub = 0 * tdi result = tdi - tdarr - tm.assert_equal(result, expected) + tm.assert_equal(result, expected_sub) result = tdarr - tdi - tm.assert_equal(result, expected) + tm.assert_equal(result, expected_sub) def test_td64arr_add_sub_tdi(self, box_with_array, names): # GH#17250 make sure result dtype is correct @@ -1263,37 +1254,25 @@ def test_td64arr_add_sub_tdi(self, box_with_array, names): tm.assert_equal(result, -expected) assert_dtype(result, "timedelta64[ns]") - def test_td64arr_add_sub_td64_nat(self, box_with_array): - # GH#23320 special handling for timedelta64("NaT") + @pytest.mark.parametrize("tdnat", [np.timedelta64("NaT"), NaT]) + def test_td64arr_add_sub_td64_nat(self, box_with_array, tdnat): + # GH#18808, GH#23320 special handling for timedelta64("NaT") box = box_with_array tdi = TimedeltaIndex([NaT, Timedelta("1s")]) - other = np.timedelta64("NaT") expected = TimedeltaIndex(["NaT"] * 2) obj = tm.box_expected(tdi, box) expected = tm.box_expected(expected, box) - result = obj + other + result = obj + tdnat tm.assert_equal(result, expected) - result = other + obj + result = tdnat + obj tm.assert_equal(result, expected) - result = obj - other + result = obj - tdnat tm.assert_equal(result, expected) - result = other - obj + result = tdnat - obj tm.assert_equal(result, expected) - def test_td64arr_sub_NaT(self, box_with_array): - # GH#18808 - box = box_with_array - ser = Series([NaT, Timedelta("1s")]) - expected = Series([NaT, NaT], dtype="timedelta64[ns]") - - ser = tm.box_expected(ser, box) - expected = tm.box_expected(expected, box) - - res = ser - NaT - tm.assert_equal(res, expected) - def test_td64arr_add_timedeltalike(self, two_hours, box_with_array): # only test adding/sub offsets as + is now numeric # GH#10699 for Tick cases @@ -1328,7 +1307,7 @@ def test_td64arr_sub_timedeltalike(self, two_hours, box_with_array): # ------------------------------------------------------------------ # __add__/__sub__ with DateOffsets and arrays of DateOffsets - def test_td64arr_add_offset_index(self, names, box_with_array): + def test_td64arr_add_sub_offset_index(self, names, box_with_array): # GH#18849, GH#19744 box = box_with_array exname = get_expected_name(box, names) @@ -1340,8 +1319,13 @@ def test_td64arr_add_offset_index(self, names, box_with_array): expected = TimedeltaIndex( [tdi[n] + other[n] for n in range(len(tdi))], freq="infer", name=exname ) + expected_sub = TimedeltaIndex( + [tdi[n] - other[n] for n in range(len(tdi))], freq="infer", name=exname + ) + tdi = tm.box_expected(tdi, box) expected = tm.box_expected(expected, box) + expected_sub = tm.box_expected(expected_sub, box) with tm.assert_produces_warning(PerformanceWarning): res = tdi + other @@ -1351,10 +1335,12 @@ def test_td64arr_add_offset_index(self, names, box_with_array): res2 = other + tdi tm.assert_equal(res2, expected) - # TODO: combine with test_td64arr_add_offset_index by parametrizing - # over second box? - def test_td64arr_add_offset_array(self, box_with_array): - # GH#18849 + with tm.assert_produces_warning(PerformanceWarning): + res_sub = tdi - other + tm.assert_equal(res_sub, expected_sub) + + def test_td64arr_add_sub_offset_array(self, box_with_array): + # GH#18849, GH#18824 box = box_with_array tdi = TimedeltaIndex(["1 days 00:00:00", "3 days 04:00:00"]) other = np.array([offsets.Hour(n=1), offsets.Minute(n=-2)]) @@ -1362,6 +1348,9 @@ def test_td64arr_add_offset_array(self, box_with_array): expected = TimedeltaIndex( [tdi[n] + other[n] for n in range(len(tdi))], freq="infer" ) + expected_sub = TimedeltaIndex( + [tdi[n] - other[n] for n in range(len(tdi))], freq="infer" + ) tdi = tm.box_expected(tdi, box) expected = tm.box_expected(expected, box) @@ -1374,41 +1363,10 @@ def test_td64arr_add_offset_array(self, box_with_array): res2 = other + tdi tm.assert_equal(res2, expected) - def test_td64arr_sub_offset_index(self, names, box_with_array): - # GH#18824, GH#19744 - box = box_with_array - xbox = box if box not in [tm.to_array, pd.array] else pd.Index - exname = get_expected_name(box, names) - - tdi = TimedeltaIndex(["1 days 00:00:00", "3 days 04:00:00"], name=names[0]) - other = pd.Index([offsets.Hour(n=1), offsets.Minute(n=-2)], name=names[1]) - - expected = TimedeltaIndex( - [tdi[n] - other[n] for n in range(len(tdi))], freq="infer", name=exname - ) - - tdi = tm.box_expected(tdi, box) - expected = tm.box_expected(expected, xbox) - + expected_sub = tm.box_expected(expected_sub, box_with_array) with tm.assert_produces_warning(PerformanceWarning): - res = tdi - other - tm.assert_equal(res, expected) - - def test_td64arr_sub_offset_array(self, box_with_array): - # GH#18824 - tdi = TimedeltaIndex(["1 days 00:00:00", "3 days 04:00:00"]) - other = np.array([offsets.Hour(n=1), offsets.Minute(n=-2)]) - - expected = TimedeltaIndex( - [tdi[n] - other[n] for n in range(len(tdi))], freq="infer" - ) - - tdi = tm.box_expected(tdi, box_with_array) - expected = tm.box_expected(expected, box_with_array) - - with tm.assert_produces_warning(PerformanceWarning): - res = tdi - other - tm.assert_equal(res, expected) + res_sub = tdi - other + tm.assert_equal(res_sub, expected_sub) def test_td64arr_with_offset_series(self, names, box_with_array): # GH#18849 @@ -1968,10 +1926,12 @@ def test_td64arr_mul_tdscalar_invalid(self, box_with_array, scalar_td): def test_td64arr_mul_too_short_raises(self, box_with_array): idx = TimedeltaIndex(np.arange(5, dtype="int64")) idx = tm.box_expected(idx, box_with_array) - msg = ( - "cannot use operands with types dtype|" - "Cannot multiply with unequal lengths|" - "Unable to coerce to Series" + msg = "|".join( + [ + "cannot use operands with types dtype", + "Cannot multiply with unequal lengths", + "Unable to coerce to Series", + ] ) with pytest.raises(TypeError, match=msg): # length check before dtype check @@ -2079,12 +2039,14 @@ def test_td64arr_div_numeric_array( result = tdser / vector tm.assert_equal(result, expected) - pattern = ( - "true_divide'? cannot use operands|" - "cannot perform __div__|" - "cannot perform __truediv__|" - "unsupported operand|" - "Cannot divide" + pattern = "|".join( + [ + "true_divide'? cannot use operands", + "cannot perform __div__", + "cannot perform __truediv__", + "unsupported operand", + "Cannot divide", + ] ) with pytest.raises(TypeError, match=pattern): vector / tdser diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index ac181af7875b5..7efd3bdb6920a 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -233,9 +233,9 @@ def test_getitem_integer_with_missing_raises(self, data, idx): # FIXME: dont leave commented-out # TODO: this raises KeyError about labels not found (it tries label-based) # import pandas._testing as tm - # s = pd.Series(data, index=[tm.rands(4) for _ in range(len(data))]) + # ser = pd.Series(data, index=[tm.rands(4) for _ in range(len(data))]) # with pytest.raises(ValueError, match=msg): - # s[idx] + # ser[idx] def test_getitem_slice(self, data): # getitem[slice] should return an array diff --git a/pandas/tests/extension/test_integer.py b/pandas/tests/extension/test_integer.py index 344b0be20fc7b..c9c0a4de60a46 100644 --- a/pandas/tests/extension/test_integer.py +++ b/pandas/tests/extension/test_integer.py @@ -115,15 +115,16 @@ def check_opname(self, s, op_name, other, exc=None): def _check_op(self, s, op, other, op_name, exc=NotImplementedError): if exc is None: sdtype = tm.get_dtype(s) - if sdtype.is_unsigned_integer and (op_name == "__rsub__"): - # TODO see https://github.com/pandas-dev/pandas/issues/22023 - pytest.skip("unsigned subtraction gives negative values") if ( hasattr(other, "dtype") and not is_extension_array_dtype(other.dtype) and is_integer_dtype(other.dtype) + and sdtype.is_unsigned_integer ): + # TODO: comment below is inaccurate; other can be int8, int16, ... + # and the trouble is that e.g. if s is UInt8 and other is int8, + # then result is UInt16 # other is np.int64 and would therefore always result in # upcasting, so keeping other as same numpy_dtype other = other.astype(sdtype.numpy_dtype) @@ -133,20 +134,9 @@ def _check_op(self, s, op, other, op_name, exc=NotImplementedError): if op_name in ("__rtruediv__", "__truediv__", "__div__"): expected = expected.fillna(np.nan).astype("Float64") - elif op_name.startswith("__r"): - # TODO reverse operators result in object dtype - # see https://github.com/pandas-dev/pandas/issues/22024 - expected = expected.astype(sdtype) - result = result.astype(sdtype) else: # combine method result in 'biggest' (int64) dtype expected = expected.astype(sdtype) - pass - - if (op_name == "__rpow__") and isinstance(other, pd.Series): - # TODO pow on Int arrays gives different result with NA - # see https://github.com/pandas-dev/pandas/issues/22022 - result = result.fillna(1) self.assert_equal(result, expected) else: diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index 1ea436520bf20..74460a75d7b63 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -1165,12 +1165,10 @@ def test_getitem_boolean_indexing_mixed(self): def test_type_error_multiindex(self): # See gh-12218 - df = DataFrame( - columns=["i", "c", "x", "y"], - data=[[0, 0, 1, 2], [1, 0, 3, 4], [0, 1, 1, 2], [1, 1, 3, 4]], + mi = MultiIndex.from_product([["x", "y"], [0, 1]], names=[None, "c"]) + dg = DataFrame( + [[1, 1, 2, 2], [3, 3, 4, 4]], columns=mi, index=Index([0, 1], name="i") ) - dg = df.pivot_table(index="i", columns="c", values=["x", "y"]) - # TODO: Is this test for pivot_table? with pytest.raises(TypeError, match="unhashable type"): dg[:, 0] diff --git a/pandas/tests/indexes/test_any_index.py b/pandas/tests/indexes/test_any_index.py index f68bde2188e67..2313afcae607a 100644 --- a/pandas/tests/indexes/test_any_index.py +++ b/pandas/tests/indexes/test_any_index.py @@ -1,7 +1,5 @@ """ Tests that can be parametrized over _any_ Index object. - -TODO: consider using hypothesis for these. """ import re diff --git a/pandas/tests/indexes/timedeltas/test_indexing.py b/pandas/tests/indexes/timedeltas/test_indexing.py index 669bbe23af559..fc8abb83ed302 100644 --- a/pandas/tests/indexes/timedeltas/test_indexing.py +++ b/pandas/tests/indexes/timedeltas/test_indexing.py @@ -248,8 +248,7 @@ def test_take_invalid_kwargs(self): with pytest.raises(ValueError, match=msg): idx.take(indices, mode="clip") - # TODO: This method came from test_timedelta; de-dup with version above - def test_take2(self): + def test_take_equiv_getitem(self): tds = ["1day 02:00:00", "1 day 04:00:00", "1 day 10:00:00"] idx = timedelta_range(start="1d", end="2d", freq="H", name="idx") expected = TimedeltaIndex(tds, freq=None, name="idx") diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 95da68510be6b..d9bd8f6809c73 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -239,7 +239,7 @@ def test_repr_truncation(self): assert "..." not in repr(df) def test_repr_deprecation_negative_int(self): - # FIXME: remove in future version after deprecation cycle + # TODO(2.0): remove in future version after deprecation cycle # Non-regression test for: # https://github.com/pandas-dev/pandas/issues/31532 width = get_option("display.max_colwidth") diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index 6d269a27e2656..f74cab9ed04da 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -6,7 +6,6 @@ timedelta, ) import pickle -import sys import numpy as np import pytest @@ -1526,14 +1525,8 @@ def _check_plot_works(f, freq=None, series=None, *args, **kwargs): with tm.ensure_clean(return_filelike=True) as path: plt.savefig(path) - # GH18439 - # this is supported only in Python 3 pickle since - # pickle in Python2 doesn't support instancemethod pickling - # TODO(statsmodels 0.10.0): Remove the statsmodels check - # https://github.com/pandas-dev/pandas/issues/24088 - # https://github.com/statsmodels/statsmodels/issues/4772 - if "statsmodels" not in sys.modules: - with tm.ensure_clean(return_filelike=True) as path: - pickle.dump(fig, path) + # GH18439, GH#24088, statsmodels#4772 + with tm.ensure_clean(return_filelike=True) as path: + pickle.dump(fig, path) finally: plt.close(fig) diff --git a/pandas/tests/series/indexing/test_datetime.py b/pandas/tests/series/indexing/test_datetime.py index 2c5c977624470..b8291471225d7 100644 --- a/pandas/tests/series/indexing/test_datetime.py +++ b/pandas/tests/series/indexing/test_datetime.py @@ -137,14 +137,14 @@ def test_getitem_setitem_datetimeindex(): tm.assert_series_equal(result, expected) # But we do not give datetimes a pass on tzawareness compat - # TODO: do the same with Timestamps and dt64 msg = "Cannot compare tz-naive and tz-aware datetime-like objects" naive = datetime(1990, 1, 1, 4) - with tm.assert_produces_warning(FutureWarning): - # GH#36148 will require tzawareness compat - result = ts[naive] - expected = ts[4] - assert result == expected + for key in [naive, Timestamp(naive), np.datetime64(naive, "ns")]: + with tm.assert_produces_warning(FutureWarning): + # GH#36148 will require tzawareness compat + result = ts[key] + expected = ts[4] + assert result == expected result = ts.copy() with tm.assert_produces_warning(FutureWarning): diff --git a/pandas/tests/series/methods/test_between.py b/pandas/tests/series/methods/test_between.py index 9c11b71e4bee6..d81017633ff76 100644 --- a/pandas/tests/series/methods/test_between.py +++ b/pandas/tests/series/methods/test_between.py @@ -11,8 +11,6 @@ class TestBetween: - - # TODO: redundant with test_between_datetime_values? def test_between(self): series = Series(date_range("1/1/2000", periods=10)) left, right = series[[2, 7]] @@ -21,7 +19,7 @@ def test_between(self): expected = (series >= left) & (series <= right) tm.assert_series_equal(result, expected) - def test_between_datetime_values(self): + def test_between_datetime_object_dtype(self): ser = Series(bdate_range("1/1/2000", periods=20).astype(object)) ser[::2] = np.nan diff --git a/pandas/tests/series/methods/test_rename.py b/pandas/tests/series/methods/test_rename.py index 2930c657eb3b2..a78abfa63cff4 100644 --- a/pandas/tests/series/methods/test_rename.py +++ b/pandas/tests/series/methods/test_rename.py @@ -1,6 +1,7 @@ from datetime import datetime import numpy as np +import pytest from pandas import ( Index, @@ -65,10 +66,9 @@ def test_rename_axis_supported(self): ser = Series(range(5)) ser.rename({}, axis=0) ser.rename({}, axis="index") - # FIXME: dont leave commented-out - # TODO: clean up shared index validation - # with pytest.raises(ValueError, match="No axis named 5"): - # ser.rename({}, axis=5) + + with pytest.raises(ValueError, match="No axis named 5"): + ser.rename({}, axis=5) def test_rename_inplace(self, datetime_series): renamer = lambda x: x.strftime("%Y%m%d") diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 4d1c75da72399..103130484f0e1 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -251,6 +251,7 @@ def test_add_corner_cases(self, datetime_series): # deltas5 = deltas * 5 # deltas = deltas + sub_deltas + def test_add_float_plus_int(self, datetime_series): # float + int int_ts = datetime_series.astype(int)[:-5] added = datetime_series + int_ts