Skip to content

CLN: ops, unnecessary mixin #37111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 18 additions & 21 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
from pandas.core.arrays import DatetimeArray, TimedeltaArray

DTScalarOrNaT = Union[DatetimeLikeScalar, NaTType]
DatetimeLikeArrayT = TypeVar("DatetimeLikeArrayT", bound="DatetimeLikeArrayMixin")


class InvalidComparison(Exception):
Expand All @@ -86,7 +87,20 @@ class InvalidComparison(Exception):
pass


class AttributesMixin:
class DatetimeLikeArrayMixin(OpsMixin, NDArrayBackedExtensionArray):
"""
Shared Base/Mixin class for DatetimeArray, TimedeltaArray, PeriodArray

Assumes that __new__/__init__ defines:
_data
_freq

and that the inheriting class has methods:
_generate_range
"""

_is_recognized_dtype: Callable[[DtypeObj], bool]
_recognized_scalars: Tuple[Type, ...]
_data: np.ndarray

def __init__(self, data, dtype=None, freq=None, copy=False):
Expand Down Expand Up @@ -184,25 +198,6 @@ def _check_compatible_with(
"""
raise AbstractMethodError(self)


DatetimeLikeArrayT = TypeVar("DatetimeLikeArrayT", bound="DatetimeLikeArrayMixin")


class DatetimeLikeArrayMixin(OpsMixin, AttributesMixin, NDArrayBackedExtensionArray):
"""
Shared Base/Mixin class for DatetimeArray, TimedeltaArray, PeriodArray

Assumes that __new__/__init__ defines:
_data
_freq

and that the inheriting class has methods:
_generate_range
"""

_is_recognized_dtype: Callable[[DtypeObj], bool]
_recognized_scalars: Tuple[Type, ...]

# ------------------------------------------------------------------
# NDArrayBackedExtensionArray compat

Expand Down Expand Up @@ -861,7 +856,9 @@ def _cmp_method(self, other, op):
# comparison otherwise it would fail to raise when
# comparing tz-aware and tz-naive
with np.errstate(all="ignore"):
result = ops.comp_method_OBJECT_ARRAY(op, self.astype(object), other)
result = ops.comp_method_OBJECT_ARRAY(
op, np.asarray(self.astype(object)), other
)
return result

other_i8 = self._unbox(other)
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
from pandas.core.ops.common import unpack_zerodim_and_defer # noqa:F401
from pandas.core.ops.docstrings import (
_flex_comp_doc_FRAME,
_make_flex_doc,
_op_descriptions,
make_flex_doc,
)
from pandas.core.ops.invalid import invalid_comparison # noqa:F401
from pandas.core.ops.mask_ops import kleene_and, kleene_or, kleene_xor # noqa: F401
Expand Down Expand Up @@ -209,7 +209,7 @@ def align_method_SERIES(left: "Series", right, align_asobject: bool = False):

def flex_method_SERIES(op):
name = op.__name__.strip("_")
doc = _make_flex_doc(name, "series")
doc = make_flex_doc(name, "series")

@Appender(doc)
def flex_wrapper(self, other, level=None, fill_value=None, axis=0):
Expand Down Expand Up @@ -445,7 +445,7 @@ def flex_arith_method_FRAME(op):
default_axis = "columns"

na_op = get_array_op(op)
doc = _make_flex_doc(op_name, "dataframe")
doc = make_flex_doc(op_name, "dataframe")

@Appender(doc)
def f(self, other, axis=default_axis, level=None, fill_value=None):
Expand Down
14 changes: 7 additions & 7 deletions pandas/core/ops/array_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def comp_method_OBJECT_ARRAY(op, x, y):
return result.reshape(x.shape)


def masked_arith_op(x: np.ndarray, y, op):
def _masked_arith_op(x: np.ndarray, y, op):
"""
If the given arithmetic operation fails, attempt it again on
only the non-null elements of the input array(s).
Expand Down Expand Up @@ -116,7 +116,7 @@ def masked_arith_op(x: np.ndarray, y, op):
return result


def na_arithmetic_op(left, right, op, is_cmp: bool = False):
def _na_arithmetic_op(left, right, op, is_cmp: bool = False):
"""
Return the result of evaluating op on the passed in values.

Expand Down Expand Up @@ -147,7 +147,7 @@ def na_arithmetic_op(left, right, op, is_cmp: bool = False):
# In this case we do not fall back to the masked op, as that
# will handle complex numbers incorrectly, see GH#32047
raise
result = masked_arith_op(left, right, op)
result = _masked_arith_op(left, right, op)

if is_cmp and (is_scalar(result) or result is NotImplemented):
# numpy returned a scalar instead of operating element-wise
Expand Down Expand Up @@ -179,15 +179,15 @@ def arithmetic_op(left: ArrayLike, right: Any, op):
# on `left` and `right`.
lvalues = maybe_upcast_datetimelike_array(left)
rvalues = maybe_upcast_datetimelike_array(right)
rvalues = maybe_upcast_for_op(rvalues, lvalues.shape)
rvalues = _maybe_upcast_for_op(rvalues, lvalues.shape)

if should_extension_dispatch(lvalues, rvalues) or isinstance(rvalues, Timedelta):
# Timedelta is included because numexpr will fail on it, see GH#31457
res_values = op(lvalues, rvalues)

else:
with np.errstate(all="ignore"):
res_values = na_arithmetic_op(lvalues, rvalues, op)
res_values = _na_arithmetic_op(lvalues, rvalues, op)

return res_values

Expand Down Expand Up @@ -248,7 +248,7 @@ def comparison_op(left: ArrayLike, right: Any, op) -> ArrayLike:
# suppress warnings from numpy about element-wise comparison
warnings.simplefilter("ignore", DeprecationWarning)
with np.errstate(all="ignore"):
res_values = na_arithmetic_op(lvalues, rvalues, op, is_cmp=True)
res_values = _na_arithmetic_op(lvalues, rvalues, op, is_cmp=True)

return res_values

Expand Down Expand Up @@ -427,7 +427,7 @@ def maybe_upcast_datetimelike_array(obj: ArrayLike) -> ArrayLike:
return obj


def maybe_upcast_for_op(obj, shape: Tuple[int, ...]):
def _maybe_upcast_for_op(obj, shape: Tuple[int, ...]):
"""
Cast non-pandas objects to pandas types to unify behavior of arithmetic
and comparison operations.
Expand Down
29 changes: 1 addition & 28 deletions pandas/core/ops/docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Dict, Optional


def _make_flex_doc(op_name, typ: str):
def make_flex_doc(op_name: str, typ: str) -> str:
"""
Make the appropriate substitutions for the given operation and class-typ
into either _flex_doc_SERIES or _flex_doc_FRAME to return the docstring
Expand Down Expand Up @@ -427,33 +427,6 @@ def _make_flex_doc(op_name, typ: str):
Series.{reverse} : {see_also_desc}.
"""

_arith_doc_FRAME = """
Binary operator %s with support to substitute a fill_value for missing data in
one of the inputs
Parameters
----------
other : Series, DataFrame, or constant
axis : {0, 1, 'index', 'columns'}
For Series input, axis to match Series index on
fill_value : None or float value, default None
Fill existing missing (NaN) values, and any new element needed for
successful DataFrame alignment, with this value before computation.
If data in both corresponding DataFrame locations is missing
the result will be missing
level : int or name
Broadcast across a level, matching Index values on the
passed MultiIndex level
Returns
-------
result : DataFrame
Notes
-----
Mismatched indices will be unioned together
"""

_flex_doc_FRAME = """
Get {desc} of dataframe and other, element-wise (binary operator `{op_name}`).
Expand Down
2 changes: 0 additions & 2 deletions scripts/validate_unwanted_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@
"_get_version",
"__main__",
"_transform_template",
"_arith_doc_FRAME",
"_flex_comp_doc_FRAME",
"_make_flex_doc",
"_op_descriptions",
"_IntegerDtype",
"_use_inf_as_na",
Expand Down