From 066a16c164fd83745888f8c67b3988c55d10ce87 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 30 Nov 2020 02:53:16 +0100 Subject: [PATCH] Revert "DEPR: ExtensionOpsMixin -> OpsMixin (#38142)" (#38158) This reverts commit f65f0d3edb275faf37435ba1fa2780240b105b48. --- doc/source/whatsnew/v1.2.0.rst | 1 - pandas/core/arrays/base.py | 16 ------- pandas/tests/arrays/test_deprecations.py | 19 -------- pandas/tests/extension/decimal/array.py | 44 +++---------------- .../tests/extension/decimal/test_decimal.py | 7 ++- 5 files changed, 11 insertions(+), 76 deletions(-) delete mode 100644 pandas/tests/arrays/test_deprecations.py diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 3fab4850dd1ec..1f8fa1e2072fd 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -492,7 +492,6 @@ Deprecations - Deprecated :meth:`Index.asi8` for :class:`Index` subclasses other than :class:`.DatetimeIndex`, :class:`.TimedeltaIndex`, and :class:`PeriodIndex` (:issue:`37877`) - The ``inplace`` parameter of :meth:`Categorical.remove_unused_categories` is deprecated and will be removed in a future version (:issue:`37643`) - The ``null_counts`` parameter of :meth:`DataFrame.info` is deprecated and replaced by ``show_counts``. It will be removed in a future version (:issue:`37999`) -- :class:`ExtensionOpsMixin` and :class:`ExtensionScalarOpsMixin` are deprecated and will be removed in a future version. Use ``pd.core.arraylike.OpsMixin`` instead (:issue:`37080`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index e3469bba23ccd..76b7877b0ac70 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -21,7 +21,6 @@ Union, cast, ) -import warnings import numpy as np @@ -1238,21 +1237,6 @@ class ExtensionOpsMixin: with NumPy arrays. """ - def __init_subclass__(cls, **kwargs): - # We use __init_subclass__ to handle deprecations - super().__init_subclass__() - - if cls.__name__ != "ExtensionScalarOpsMixin": - # We only want to warn for user-defined subclasses, - # and cannot reference ExtensionScalarOpsMixin directly at this point. - warnings.warn( - "ExtensionOpsMixin and ExtensionScalarOpsMixin are deprecated " - "and will be removed in a future version. Use " - "pd.core.arraylike.OpsMixin instead.", - FutureWarning, - stacklevel=2, - ) - @classmethod def _create_arithmetic_method(cls, op): raise AbstractMethodError(cls) diff --git a/pandas/tests/arrays/test_deprecations.py b/pandas/tests/arrays/test_deprecations.py deleted file mode 100644 index 7e80072e8794f..0000000000000 --- a/pandas/tests/arrays/test_deprecations.py +++ /dev/null @@ -1,19 +0,0 @@ -import pandas._testing as tm -from pandas.core.arrays import ( - ExtensionArray, - ExtensionOpsMixin, - ExtensionScalarOpsMixin, -) - - -def test_extension_ops_mixin_deprecated(): - # GH#37080 deprecated in favor of OpsMixin - with tm.assert_produces_warning(FutureWarning): - - class MySubclass(ExtensionOpsMixin, ExtensionArray): - pass - - with tm.assert_produces_warning(FutureWarning): - - class MyOtherSubclass(ExtensionScalarOpsMixin, ExtensionArray): - pass diff --git a/pandas/tests/extension/decimal/array.py b/pandas/tests/extension/decimal/array.py index d7bdca4b218b5..a713550dafa5c 100644 --- a/pandas/tests/extension/decimal/array.py +++ b/pandas/tests/extension/decimal/array.py @@ -7,13 +7,12 @@ import numpy as np from pandas.core.dtypes.base import ExtensionDtype -from pandas.core.dtypes.cast import maybe_cast_to_extension_array from pandas.core.dtypes.common import is_dtype_equal, is_list_like, pandas_dtype import pandas as pd from pandas.api.extensions import no_default, register_extension_dtype from pandas.core.arraylike import OpsMixin -from pandas.core.arrays import ExtensionArray +from pandas.core.arrays import ExtensionArray, ExtensionScalarOpsMixin from pandas.core.indexers import check_array_indexer @@ -46,7 +45,7 @@ def _is_numeric(self) -> bool: return True -class DecimalArray(OpsMixin, ExtensionArray): +class DecimalArray(OpsMixin, ExtensionScalarOpsMixin, ExtensionArray): __array_priority__ = 1000 def __init__(self, values, dtype=None, copy=False, context=None): @@ -226,42 +225,6 @@ def convert_values(param): return np.asarray(res, dtype=bool) - _do_coerce = True # overriden in DecimalArrayWithoutCoercion - - def _arith_method(self, other, op): - def convert_values(param): - if isinstance(param, ExtensionArray) or is_list_like(param): - ovalues = param - else: # Assume its an object - ovalues = [param] * len(self) - return ovalues - - lvalues = self - rvalues = convert_values(other) - - # If the operator is not defined for the underlying objects, - # a TypeError should be raised - res = [op(a, b) for (a, b) in zip(lvalues, rvalues)] - - def _maybe_convert(arr): - if self._do_coerce: - # https://github.com/pandas-dev/pandas/issues/22850 - # We catch all regular exceptions here, and fall back - # to an ndarray. - res = maybe_cast_to_extension_array(type(self), arr) - if not isinstance(res, type(self)): - # exception raised in _from_sequence; ensure we have ndarray - res = np.asarray(arr) - else: - res = np.asarray(arr) - return res - - if op.__name__ in {"divmod", "rdivmod"}: - a, b = zip(*res) - return _maybe_convert(a), _maybe_convert(b) - - return _maybe_convert(res) - def to_decimal(values, context=None): return DecimalArray([decimal.Decimal(x) for x in values], context=context) @@ -269,3 +232,6 @@ def to_decimal(values, context=None): def make_data(): return [decimal.Decimal(random.random()) for _ in range(100)] + + +DecimalArray._add_arithmetic_ops() diff --git a/pandas/tests/extension/decimal/test_decimal.py b/pandas/tests/extension/decimal/test_decimal.py index c3e84f75ebe68..233b658d29782 100644 --- a/pandas/tests/extension/decimal/test_decimal.py +++ b/pandas/tests/extension/decimal/test_decimal.py @@ -335,7 +335,12 @@ def _from_sequence(cls, scalars, dtype=None, copy=False): class DecimalArrayWithoutCoercion(DecimalArrayWithoutFromSequence): - _do_coerce = False + @classmethod + def _create_arithmetic_method(cls, op): + return cls._create_method(op, coerce_to_dtype=False) + + +DecimalArrayWithoutCoercion._add_arithmetic_ops() def test_combine_from_sequence_raises():