diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 1339dee954603..4dc14397a30f4 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -3565,7 +3565,7 @@ cpdef to_offset(freq): f"to_offset does not support tuples {freq}, pass as a string instead" ) - elif isinstance(freq, timedelta): + elif PyDelta_Check(freq): return delta_to_tick(freq) elif isinstance(freq, str): diff --git a/pandas/conftest.py b/pandas/conftest.py index 2862f7c957abc..9fc1f0509d232 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -1002,14 +1002,6 @@ def tz_aware_fixture(request): tz_aware_fixture2 = tz_aware_fixture -@pytest.fixture(scope="module") -def datetime_tz_utc(): - """ - Yields the UTC timezone object from the datetime module. - """ - return timezone.utc - - @pytest.fixture(params=["utc", "dateutil/UTC", utc, tzutc(), timezone.utc]) def utc_fixture(request): """ @@ -1189,7 +1181,7 @@ def any_nullable_int_dtype(request): @pytest.fixture(params=tm.ALL_EA_INT_DTYPES + tm.FLOAT_EA_DTYPES) -def any_numeric_dtype(request): +def any_nullable_numeric_dtype(request): """ Parameterized fixture for any nullable integer dtype and any float ea dtypes. diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 7f4e16dc236ac..94c7d325d0bc8 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -658,7 +658,7 @@ def _astype(self, dtype: DtypeObj, copy: bool) -> ArrayLike: values = values.astype(dtype, copy=copy) else: - values = astype_nansafe(values, dtype, copy=True) + values = astype_nansafe(values, dtype, copy=copy) return values diff --git a/pandas/core/internals/concat.py b/pandas/core/internals/concat.py index 013e52248f5c4..f97077954f8bf 100644 --- a/pandas/core/internals/concat.py +++ b/pandas/core/internals/concat.py @@ -413,7 +413,7 @@ def _get_empty_dtype_and_na(join_units: Sequence[JoinUnit]) -> Tuple[DtypeObj, A return np.dtype("M8[ns]"), np.datetime64("NaT", "ns") elif "timedelta" in upcast_classes: return np.dtype("m8[ns]"), np.timedelta64("NaT", "ns") - else: # pragma + else: try: common_dtype = np.find_common_type(upcast_classes, []) except TypeError: diff --git a/pandas/core/series.py b/pandas/core/series.py index 7f2039c998f53..3f22f14766a07 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -4494,7 +4494,7 @@ def replace( method=method, ) - def _replace_single(self, to_replace, method, inplace, limit): + def _replace_single(self, to_replace, method: str, inplace: bool, limit): """ Replaces values in a Series using the fill method specified when no replacement value is given in the replace method diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index 341a8a9f90b96..ceaf6e1ac21e5 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -80,6 +80,8 @@ if TYPE_CHECKING: from tables import Col, File, Node + from pandas.core.internals import Block + # versioning attribute _version = "0.15.2" @@ -3860,9 +3862,6 @@ def _create_axes( for a in new_non_index_axes: obj = _reindex_axis(obj, a[0], a[1]) - def get_blk_items(mgr, blocks): - return [mgr.items.take(blk.mgr_locs) for blk in blocks] - transposed = new_index.axis == 1 # figure out data_columns and get out blocks @@ -3870,10 +3869,10 @@ def get_blk_items(mgr, blocks): data_columns, min_itemsize, new_non_index_axes ) - block_obj = self.get_object(obj, transposed)._consolidate() + frame = self.get_object(obj, transposed)._consolidate() blocks, blk_items = self._get_blocks_and_items( - block_obj, table_exists, new_non_index_axes, self.values_axes, data_columns + frame, table_exists, new_non_index_axes, self.values_axes, data_columns ) # add my values @@ -3978,27 +3977,31 @@ def get_blk_items(mgr, blocks): @staticmethod def _get_blocks_and_items( - block_obj, table_exists, new_non_index_axes, values_axes, data_columns + frame: DataFrame, + table_exists: bool, + new_non_index_axes, + values_axes, + data_columns, ): # Helper to clarify non-state-altering parts of _create_axes - def get_blk_items(mgr, blocks): - return [mgr.items.take(blk.mgr_locs) for blk in blocks] + def get_blk_items(mgr): + return [mgr.items.take(blk.mgr_locs) for blk in mgr.blocks] - blocks = block_obj._mgr.blocks - blk_items = get_blk_items(block_obj._mgr, blocks) + blocks: List["Block"] = list(frame._mgr.blocks) + blk_items: List[Index] = get_blk_items(frame._mgr) if len(data_columns): axis, axis_labels = new_non_index_axes[0] new_labels = Index(axis_labels).difference(Index(data_columns)) - mgr = block_obj.reindex(new_labels, axis=axis)._mgr + mgr = frame.reindex(new_labels, axis=axis)._mgr blocks = list(mgr.blocks) - blk_items = get_blk_items(mgr, blocks) + blk_items = get_blk_items(mgr) for c in data_columns: - mgr = block_obj.reindex([c], axis=axis)._mgr + mgr = frame.reindex([c], axis=axis)._mgr blocks.extend(mgr.blocks) - blk_items.extend(get_blk_items(mgr, mgr.blocks)) + blk_items.extend(get_blk_items(mgr)) # reorder the blocks in the same order as the existing table if we can if table_exists: @@ -4006,7 +4009,7 @@ def get_blk_items(mgr, blocks): tuple(b_items.tolist()): (b, b_items) for b, b_items in zip(blocks, blk_items) } - new_blocks = [] + new_blocks: List["Block"] = [] new_blk_items = [] for ea in values_axes: items = tuple(ea.values) @@ -4875,7 +4878,7 @@ def _unconvert_index( def _maybe_convert_for_string_atom( - name: str, block, existing_col, min_itemsize, nan_rep, encoding, errors + name: str, block: "Block", existing_col, min_itemsize, nan_rep, encoding, errors ): if not block.is_object: return block.values @@ -4895,11 +4898,12 @@ def _maybe_convert_for_string_atom( elif not (inferred_type == "string" or dtype_name == "object"): return block.values - block = block.fillna(nan_rep, downcast=False) - if isinstance(block, list): - # Note: because block is always object dtype, fillna goes - # through a path such that the result is always a 1-element list - block = block[0] + blocks: List["Block"] = block.fillna(nan_rep, downcast=False) + # Note: because block is always object dtype, fillna goes + # through a path such that the result is always a 1-element list + assert len(blocks) == 1 + block = blocks[0] + data = block.values # see if we have a valid string type diff --git a/pandas/tests/indexes/datetimes/test_timezones.py b/pandas/tests/indexes/datetimes/test_timezones.py index add1bd4bb3972..e448cf0b578ae 100644 --- a/pandas/tests/indexes/datetimes/test_timezones.py +++ b/pandas/tests/indexes/datetimes/test_timezones.py @@ -1159,7 +1159,6 @@ def test_dti_union_mixed(self): @pytest.mark.parametrize( "tz", [None, "UTC", "US/Central", dateutil.tz.tzoffset(None, -28800)] ) - @pytest.mark.usefixtures("datetime_tz_utc") def test_iteration_preserves_nanoseconds(self, tz): # GH 19603 index = DatetimeIndex( diff --git a/pandas/tests/indexes/timedeltas/test_partial_slicing.py b/pandas/tests/indexes/timedeltas/test_partial_slicing.py index e5f509acf4734..6d53fe4563e41 100644 --- a/pandas/tests/indexes/timedeltas/test_partial_slicing.py +++ b/pandas/tests/indexes/timedeltas/test_partial_slicing.py @@ -1,5 +1,4 @@ import numpy as np -import pytest from pandas import Series, timedelta_range import pandas._testing as tm @@ -22,13 +21,6 @@ def test_partial_slice(self): expected = s.iloc[:134] tm.assert_series_equal(result, expected) - result = s["6 days, 23:11:12"] - assert result == s.iloc[133] - - msg = r"^Timedelta\('50 days 00:00:00'\)$" - with pytest.raises(KeyError, match=msg): - s["50 days"] - def test_partial_slice_high_reso(self): # higher reso diff --git a/pandas/tests/series/indexing/test_getitem.py b/pandas/tests/series/indexing/test_getitem.py index 2022bca514540..a7a60f37bcd00 100644 --- a/pandas/tests/series/indexing/test_getitem.py +++ b/pandas/tests/series/indexing/test_getitem.py @@ -18,6 +18,7 @@ Timestamp, date_range, period_range, + timedelta_range, ) import pandas._testing as tm from pandas.core.indexing import IndexingError @@ -121,6 +122,23 @@ def test_getitem_scalar_categorical_index(self): result = ser[cats[0]] assert result == expected + def test_getitem_str_with_timedeltaindex(self): + rng = timedelta_range("1 day 10:11:12", freq="h", periods=500) + ser = Series(np.arange(len(rng)), index=rng) + + key = "6 days, 23:11:12" + indexer = rng.get_loc(key) + assert indexer == 133 + + result = ser[key] + assert result == ser.iloc[133] + + msg = r"^Timedelta\('50 days 00:00:00'\)$" + with pytest.raises(KeyError, match=msg): + rng.get_loc("50 days") + with pytest.raises(KeyError, match=msg): + ser["50 days"] + class TestSeriesGetitemSlices: def test_getitem_partial_str_slice_with_datetimeindex(self): diff --git a/pandas/tests/series/indexing/test_setitem.py b/pandas/tests/series/indexing/test_setitem.py index d6d0723bee0e8..47641d49c7a09 100644 --- a/pandas/tests/series/indexing/test_setitem.py +++ b/pandas/tests/series/indexing/test_setitem.py @@ -167,19 +167,19 @@ def test_setitem_boolean_td64_values_cast_na(self, value): expected = Series([NaT, 1, 2], dtype="timedelta64[ns]") tm.assert_series_equal(series, expected) - def test_setitem_boolean_nullable_int_types(self, any_numeric_dtype): + def test_setitem_boolean_nullable_int_types(self, any_nullable_numeric_dtype): # GH: 26468 - ser = Series([5, 6, 7, 8], dtype=any_numeric_dtype) - ser[ser > 6] = Series(range(4), dtype=any_numeric_dtype) - expected = Series([5, 6, 2, 3], dtype=any_numeric_dtype) + ser = Series([5, 6, 7, 8], dtype=any_nullable_numeric_dtype) + ser[ser > 6] = Series(range(4), dtype=any_nullable_numeric_dtype) + expected = Series([5, 6, 2, 3], dtype=any_nullable_numeric_dtype) tm.assert_series_equal(ser, expected) - ser = Series([5, 6, 7, 8], dtype=any_numeric_dtype) - ser.loc[ser > 6] = Series(range(4), dtype=any_numeric_dtype) + ser = Series([5, 6, 7, 8], dtype=any_nullable_numeric_dtype) + ser.loc[ser > 6] = Series(range(4), dtype=any_nullable_numeric_dtype) tm.assert_series_equal(ser, expected) - ser = Series([5, 6, 7, 8], dtype=any_numeric_dtype) - loc_ser = Series(range(4), dtype=any_numeric_dtype) + ser = Series([5, 6, 7, 8], dtype=any_nullable_numeric_dtype) + loc_ser = Series(range(4), dtype=any_nullable_numeric_dtype) ser.loc[ser > 6] = loc_ser.loc[loc_ser > 1] tm.assert_series_equal(ser, expected) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index c7bd38bbd00b9..d7cd92c8e3362 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -272,8 +272,8 @@ def test_constructor_index_dtype(self, dtype): [ ([1, 2]), (["1", "2"]), - (list(pd.date_range("1/1/2011", periods=2, freq="H"))), - (list(pd.date_range("1/1/2011", periods=2, freq="H", tz="US/Eastern"))), + (list(date_range("1/1/2011", periods=2, freq="H"))), + (list(date_range("1/1/2011", periods=2, freq="H", tz="US/Eastern"))), ([Interval(left=0, right=5)]), ], ) @@ -628,10 +628,10 @@ def test_constructor_copy(self): @pytest.mark.parametrize( "index", [ - pd.date_range("20170101", periods=3, tz="US/Eastern"), - pd.date_range("20170101", periods=3), - pd.timedelta_range("1 day", periods=3), - pd.period_range("2012Q1", periods=3, freq="Q"), + date_range("20170101", periods=3, tz="US/Eastern"), + date_range("20170101", periods=3), + timedelta_range("1 day", periods=3), + period_range("2012Q1", periods=3, freq="Q"), Index(list("abc")), pd.Int64Index([1, 2, 3]), RangeIndex(0, 3), @@ -1038,16 +1038,16 @@ def test_construction_consistency(self): # make sure that we are not re-localizing upon construction # GH 14928 - s = Series(pd.date_range("20130101", periods=3, tz="US/Eastern")) + ser = Series(date_range("20130101", periods=3, tz="US/Eastern")) - result = Series(s, dtype=s.dtype) - tm.assert_series_equal(result, s) + result = Series(ser, dtype=ser.dtype) + tm.assert_series_equal(result, ser) - result = Series(s.dt.tz_convert("UTC"), dtype=s.dtype) - tm.assert_series_equal(result, s) + result = Series(ser.dt.tz_convert("UTC"), dtype=ser.dtype) + tm.assert_series_equal(result, ser) - result = Series(s.values, dtype=s.dtype) - tm.assert_series_equal(result, s) + result = Series(ser.values, dtype=ser.dtype) + tm.assert_series_equal(result, ser) @pytest.mark.parametrize( "data_constructor", [list, np.array], ids=["list", "ndarray[object]"] @@ -1374,7 +1374,7 @@ def test_convert_non_ns(self): # convert from a numpy array of non-ns timedelta64 arr = np.array([1, 2, 3], dtype="timedelta64[s]") s = Series(arr) - expected = Series(pd.timedelta_range("00:00:01", periods=3, freq="s")) + expected = Series(timedelta_range("00:00:01", periods=3, freq="s")) tm.assert_series_equal(s, expected) # convert from a numpy array of non-ns datetime64