From 20a51c307715b1ceca9d15c6643f597f2562f100 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sun, 19 Apr 2020 18:12:57 -0700 Subject: [PATCH 1/3] CLN: make DTA/TDA check clearer --- pandas/core/indexes/datetimelike.py | 3 +-- pandas/core/indexes/multi.py | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 203ea2152886a..067ff32b85862 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -80,8 +80,7 @@ def wrapper(left, right): cache=True, ) @inherit_names( - ["mean", "freq", "freqstr", "asi8", "_box_values", "_box_func"], - DatetimeLikeArrayMixin, + ["mean", "freq", "freqstr", "asi8", "_box_func"], DatetimeLikeArrayMixin, ) class DatetimeIndexOpsMixin(ExtensionIndex): """ diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index d411867af2ef8..4076b01d2f029 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -36,8 +36,7 @@ is_scalar, pandas_dtype, ) -from pandas.core.dtypes.dtypes import ExtensionDtype -from pandas.core.dtypes.generic import ABCDataFrame +from pandas.core.dtypes.generic import ABCDataFrame, ABCExtensionArray from pandas.core.dtypes.missing import array_equivalent, isna import pandas.core.algorithms as algos @@ -653,7 +652,8 @@ def values(self): vals = self._get_level_values(i) if is_categorical_dtype(vals): vals = vals._internal_get_values() - if isinstance(vals.dtype, ExtensionDtype) or hasattr(vals, "_box_values"): + if isinstance(vals._data, ABCExtensionArray): + # Includes DatetimeArray and TimedeltaArray vals = vals.astype(object) vals = np.array(vals, copy=False) values.append(vals) From 09cf92c55e570cebb8586c09d9a5350c39213e06 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sun, 19 Apr 2020 20:08:56 -0700 Subject: [PATCH 2/3] revert rebase mixup --- pandas/core/indexes/datetimelike.py | 3 ++- pandas/core/indexes/multi.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 067ff32b85862..203ea2152886a 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -80,7 +80,8 @@ def wrapper(left, right): cache=True, ) @inherit_names( - ["mean", "freq", "freqstr", "asi8", "_box_func"], DatetimeLikeArrayMixin, + ["mean", "freq", "freqstr", "asi8", "_box_values", "_box_func"], + DatetimeLikeArrayMixin, ) class DatetimeIndexOpsMixin(ExtensionIndex): """ diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 4076b01d2f029..d411867af2ef8 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -36,7 +36,8 @@ is_scalar, pandas_dtype, ) -from pandas.core.dtypes.generic import ABCDataFrame, ABCExtensionArray +from pandas.core.dtypes.dtypes import ExtensionDtype +from pandas.core.dtypes.generic import ABCDataFrame from pandas.core.dtypes.missing import array_equivalent, isna import pandas.core.algorithms as algos @@ -652,8 +653,7 @@ def values(self): vals = self._get_level_values(i) if is_categorical_dtype(vals): vals = vals._internal_get_values() - if isinstance(vals._data, ABCExtensionArray): - # Includes DatetimeArray and TimedeltaArray + if isinstance(vals.dtype, ExtensionDtype) or hasattr(vals, "_box_values"): vals = vals.astype(object) vals = np.array(vals, copy=False) values.append(vals) From b349e97de13b300f69e6a7d7555a852bd972504b Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sun, 19 Apr 2020 20:09:30 -0700 Subject: [PATCH 3/3] CLN: make Categorical.codes a simpler property --- pandas/core/arrays/categorical.py | 34 +++++++-------------- pandas/tests/arrays/categorical/test_api.py | 2 +- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index c5cac0cfeef6c..cdd0717849e96 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -199,17 +199,6 @@ def contains(cat, key, container): return any(loc_ in container for loc_ in loc) -_codes_doc = """ -The category codes of this categorical. - -Level codes are an array if integer which are the positions of the real -values in the categories array. - -There is not setter, use the other categorical methods and the normal item -setter to change values in the categorical. -""" - - class Categorical(ExtensionArray, PandasObject): """ Represent a categorical variable in classic R / S-plus fashion. @@ -652,27 +641,26 @@ def from_codes(cls, codes, categories=None, ordered=None, dtype=None): return cls(codes, dtype=dtype, fastpath=True) - def _get_codes(self): + @property + def codes(self) -> np.ndarray: """ - Get the codes. + The category codes of this categorical. + + Codes are an array of integers which are the positions of the actual + values in the categories array. + + There is no setter, use the other categorical methods and the normal item + setter to change values in the categorical. Returns ------- - codes : integer array view - A non writable view of the `codes` array. + ndarray[int] + A non-writable view of the `codes` array. """ v = self._codes.view() v.flags.writeable = False return v - def _set_codes(self, codes): - """ - Not settable by the user directly - """ - raise ValueError("cannot set Categorical codes directly") - - codes = property(fget=_get_codes, fset=_set_codes, doc=_codes_doc) - def _set_categories(self, categories, fastpath=False): """ Sets new categories inplace diff --git a/pandas/tests/arrays/categorical/test_api.py b/pandas/tests/arrays/categorical/test_api.py index 691230620c2e8..6fce4b4145ff2 100644 --- a/pandas/tests/arrays/categorical/test_api.py +++ b/pandas/tests/arrays/categorical/test_api.py @@ -464,7 +464,7 @@ def test_codes_immutable(self): tm.assert_numpy_array_equal(c.codes, exp) # Assignments to codes should raise - with pytest.raises(ValueError, match="cannot set Categorical codes directly"): + with pytest.raises(AttributeError, match="can't set attribute"): c.codes = np.array([0, 1, 2, 0, 1], dtype="int8") # changes in the codes array should raise