From c98ecb091fc0738bf4b87d89beb0837b5ff90ed9 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 5 Mar 2020 15:49:31 -0800 Subject: [PATCH 1/4] cleanups --- pandas/core/indexes/accessors.py | 9 +++++++-- pandas/core/internals/managers.py | 6 +++--- pandas/core/series.py | 4 ---- pandas/tseries/frequencies.py | 7 ++----- setup.cfg | 2 ++ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pandas/core/indexes/accessors.py b/pandas/core/indexes/accessors.py index db774a03c02f8..3d88f3ac31373 100644 --- a/pandas/core/indexes/accessors.py +++ b/pandas/core/indexes/accessors.py @@ -1,6 +1,8 @@ """ datetimelike delegation """ +from typing import TYPE_CHECKING + import numpy as np from pandas.core.dtypes.common import ( @@ -21,9 +23,12 @@ from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.timedeltas import TimedeltaIndex +if TYPE_CHECKING: + from pandas import Series # noqa:F401 + class Properties(PandasDelegate, PandasObject, NoNewAttributesMixin): - def __init__(self, data, orig): + def __init__(self, data: "Series", orig): if not isinstance(data, ABCSeries): raise TypeError( f"cannot convert an object of type {type(data)} to a datetimelike index" @@ -303,7 +308,7 @@ class PeriodProperties(Properties): class CombinedDatetimelikeProperties( DatetimeProperties, TimedeltaProperties, PeriodProperties ): - def __new__(cls, data): + def __new__(cls, data: "Series"): # CombinedDatetimelikeProperties isn't really instantiated. Instead # we need to choose which parent (datetime or timedelta) is # appropriate. Since we're checking the dtypes anyway, we'll just diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index f6e79a0f2045d..98afc5ac3a0e3 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -24,7 +24,6 @@ is_list_like, is_numeric_v_string_like, is_scalar, - is_sparse, ) from pandas.core.dtypes.concat import concat_compat from pandas.core.dtypes.dtypes import ExtensionDtype @@ -32,6 +31,7 @@ from pandas.core.dtypes.missing import isna import pandas.core.algorithms as algos +from pandas.core.arrays.sparse import SparseDtype from pandas.core.base import PandasObject from pandas.core.indexers import maybe_convert_indices from pandas.core.indexes.api import Index, MultiIndex, ensure_index @@ -843,8 +843,8 @@ def _interleave(self) -> np.ndarray: # TODO: https://github.com/pandas-dev/pandas/issues/22791 # Give EAs some input on what happens here. Sparse needs this. - if is_sparse(dtype): - dtype = dtype.subtype # type: ignore + if isinstance(dtype, SparseDtype): + dtype = dtype.subtype elif is_extension_array_dtype(dtype): dtype = "object" diff --git a/pandas/core/series.py b/pandas/core/series.py index 12164a4b8ff6b..dc88300a596cf 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -47,7 +47,6 @@ ABCMultiIndex, ABCPeriodIndex, ABCSeries, - ABCSparseArray, ) from pandas.core.dtypes.inference import is_hashable from pandas.core.dtypes.missing import ( @@ -289,9 +288,6 @@ def __init__( pass elif isinstance(data, (set, frozenset)): raise TypeError(f"'{type(data).__name__}' type is unordered") - elif isinstance(data, ABCSparseArray): - # handle sparse passed here (and force conversion) - data = data.to_dense() else: data = com.maybe_iterable_to_list(data) diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py index 1a1b7e8e1bd08..0426351310e36 100644 --- a/pandas/tseries/frequencies.py +++ b/pandas/tseries/frequencies.py @@ -4,7 +4,6 @@ import warnings import numpy as np -from pytz import AmbiguousTimeError from pandas._libs.algos import unique_deltas from pandas._libs.tslibs import Timedelta, Timestamp @@ -288,10 +287,7 @@ def infer_freq(index, warn: bool = True) -> Optional[str]: index = index.values if not isinstance(index, pd.DatetimeIndex): - try: - index = pd.DatetimeIndex(index) - except AmbiguousTimeError: - index = pd.DatetimeIndex(index.asi8) + index = pd.DatetimeIndex(index) inferer = _FrequencyInferer(index, warn=warn) return inferer.get_freq() @@ -490,6 +486,7 @@ def _is_business_daily(self) -> bool: ) def _get_wom_rule(self) -> Optional[str]: + # FIXME: dont leave commented-out # wdiffs = unique(np.diff(self.index.week)) # We also need -47, -49, -48 to catch index spanning year boundary # if not lib.ismember(wdiffs, set([4, 5, -47, -49, -48])).all(): diff --git a/setup.cfg b/setup.cfg index bbd8489622005..5cfe6c6221453 100644 --- a/setup.cfg +++ b/setup.cfg @@ -75,6 +75,8 @@ omit = pandas/_typing.py pandas/_version.py plugins = Cython.Coverage +exclude_lines = + if TYPE_CHECKING: [coverage:report] ignore_errors = False From 698dd7428e2ff25f5c07701f11f492621f3536ec Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 5 Mar 2020 15:58:13 -0800 Subject: [PATCH 2/4] cleanups --- pandas/_libs/tslibs/timedeltas.pyx | 2 +- pandas/core/arrays/datetimes.py | 2 +- pandas/core/arrays/timedeltas.py | 2 +- pandas/core/indexes/accessors.py | 6 +++--- pandas/core/indexes/range.py | 2 +- pandas/core/nanops.py | 4 ++-- pandas/tests/frame/indexing/test_datetime.py | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 7bd02b734beeb..457f3eb0749c2 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1167,7 +1167,7 @@ class Timedelta(_Timedelta): Possible values: - * 'Y', 'M', 'W', 'D', 'T', 'S', 'L', 'U', or 'N' + * 'W', 'D', 'T', 'S', 'L', 'U', or 'N' * 'days' or 'day' * 'hours', 'hour', 'hr', or 'h' * 'minutes', 'minute', 'min', or 'm' diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 56939cda6d21c..9f19c7ba0be6e 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -988,7 +988,7 @@ def tz_localize(self, tz, ambiguous="raise", nonexistent="raise"): # ---------------------------------------------------------------- # Conversion Methods - Vectorized analogues of Timestamp methods - def to_pydatetime(self): + def to_pydatetime(self) -> np.ndarray: """ Return Datetime Array/Index as object ndarray of datetime.datetime objects. diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 749489a0a04fb..dbc0b0b3ccbbf 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -825,7 +825,7 @@ def total_seconds(self): """ return self._maybe_mask_results(1e-9 * self.asi8, fill_value=None) - def to_pytimedelta(self): + def to_pytimedelta(self) -> np.ndarray: """ Return Timedelta Array/Index as object ndarray of datetime.timedelta objects. diff --git a/pandas/core/indexes/accessors.py b/pandas/core/indexes/accessors.py index 3d88f3ac31373..71ae92df1970b 100644 --- a/pandas/core/indexes/accessors.py +++ b/pandas/core/indexes/accessors.py @@ -142,7 +142,7 @@ class DatetimeProperties(Properties): Raises TypeError if the Series does not contain datetimelike values. """ - def to_pydatetime(self): + def to_pydatetime(self) -> np.ndarray: """ Return the data as an array of native Python datetime objects. @@ -214,7 +214,7 @@ class TimedeltaProperties(Properties): Raises TypeError if the Series does not contain datetimelike values. """ - def to_pytimedelta(self): + def to_pytimedelta(self) -> np.ndarray: """ Return an array of native `datetime.timedelta` objects. @@ -276,7 +276,7 @@ def components(self): 2 0 0 0 2 0 0 0 3 0 0 0 3 0 0 0 4 0 0 0 4 0 0 0 - """ # noqa: E501 + """ return self._get_values().components.set_index(self._parent.index) @property diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index f621a3c153adf..c21d8df2476b3 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -168,7 +168,7 @@ def _data(self): return self._cached_data @cache_readonly - def _int64index(self): + def _int64index(self) -> Int64Index: return Int64Index._simple_new(self._data, name=self.name) def _get_data_as_items(self): diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 4398a1569ac56..725d1adc6d161 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -981,7 +981,7 @@ def nanskew( Examples -------- >>> import pandas.core.nanops as nanops - >>> s = pd.Series([1,np.nan, 1, 2]) + >>> s = pd.Series([1, np.nan, 1, 2]) >>> nanops.nanskew(s) 1.7320508075688787 """ @@ -1065,7 +1065,7 @@ def nankurt( Examples -------- >>> import pandas.core.nanops as nanops - >>> s = pd.Series([1,np.nan, 1, 3, 2]) + >>> s = pd.Series([1, np.nan, 1, 3, 2]) >>> nanops.nankurt(s) -1.2892561983471076 """ diff --git a/pandas/tests/frame/indexing/test_datetime.py b/pandas/tests/frame/indexing/test_datetime.py index 6bfcac3793584..245d076dea0e5 100644 --- a/pandas/tests/frame/indexing/test_datetime.py +++ b/pandas/tests/frame/indexing/test_datetime.py @@ -40,7 +40,7 @@ def test_set_reset(self): # set/reset df = DataFrame({"A": [0, 1, 2]}, index=idx) result = df.reset_index() - assert result["foo"].dtype, "M8[ns, US/Eastern" + assert result["foo"].dtype == "M8[ns, US/Eastern]" df = result.set_index("foo") tm.assert_index_equal(df.index, idx) From 53fe14c2b39d79833a2d51b96824b38cea964e8f Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 5 Mar 2020 16:23:26 -0800 Subject: [PATCH 3/4] test fixup --- pandas/tests/frame/indexing/test_datetime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/indexing/test_datetime.py b/pandas/tests/frame/indexing/test_datetime.py index 245d076dea0e5..0fd60c151b9c4 100644 --- a/pandas/tests/frame/indexing/test_datetime.py +++ b/pandas/tests/frame/indexing/test_datetime.py @@ -40,7 +40,7 @@ def test_set_reset(self): # set/reset df = DataFrame({"A": [0, 1, 2]}, index=idx) result = df.reset_index() - assert result["foo"].dtype == "M8[ns, US/Eastern]" + assert result["foo"].dtype == "datetime64[ns, US/Eastern]" df = result.set_index("foo") tm.assert_index_equal(df.index, idx) From 61308e7c4d36bcb26edd6953562d53be8335288f Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 6 Mar 2020 11:07:09 -0800 Subject: [PATCH 4/4] move setup.cfg line --- setup.cfg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 5cfe6c6221453..42c507a2b6b01 100644 --- a/setup.cfg +++ b/setup.cfg @@ -75,8 +75,6 @@ omit = pandas/_typing.py pandas/_version.py plugins = Cython.Coverage -exclude_lines = - if TYPE_CHECKING: [coverage:report] ignore_errors = False @@ -100,6 +98,7 @@ exclude_lines = # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.: + if TYPE_CHECKING: [coverage:html] directory = coverage_html_report