Skip to content
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

REF: boilerplate for ops internal consistency #28037

Merged
merged 57 commits into from
Nov 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
1426061
OK
jbrockmendel Aug 9, 2019
c9e99f3
OK
jbrockmendel Aug 9, 2019
f109154
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 9, 2019
2462d9b
OK
jbrockmendel Aug 9, 2019
2289a85
OK
jbrockmendel Aug 10, 2019
68bab4b
OK
jbrockmendel Aug 10, 2019
7b00b02
OK
jbrockmendel Aug 12, 2019
c776dd7
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 12, 2019
c2e9fc6
cln
jbrockmendel Aug 12, 2019
afbd04a
remove validate_for_numeric_binop
jbrockmendel Aug 12, 2019
8af29a8
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 12, 2019
f3c9c20
OK
jbrockmendel Aug 12, 2019
2c72628
delete commented-out
jbrockmendel Aug 12, 2019
d19282d
OK
jbrockmendel Aug 12, 2019
7f337d2
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 12, 2019
242d7a0
cleanup
jbrockmendel Aug 12, 2019
fc498c0
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 12, 2019
9582d43
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 13, 2019
77cbdff
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 13, 2019
d3dafed
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 13, 2019
c539b2e
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 14, 2019
9d19cdb
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 15, 2019
e65ae3b
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 15, 2019
52c8ad3
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 15, 2019
2800a9b
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 16, 2019
d33ca40
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 16, 2019
2875b3a
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 19, 2019
f84e737
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 19, 2019
6149859
revert unnecessary
jbrockmendel Aug 19, 2019
05920a1
revert
jbrockmendel Aug 19, 2019
d6adfb0
docstring
jbrockmendel Aug 19, 2019
837d728
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 19, 2019
9eb8fbc
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 19, 2019
eb583c7
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Aug 20, 2019
9e30806
import fixup
jbrockmendel Aug 20, 2019
63d8f9c
blackify
jbrockmendel Aug 20, 2019
98f02b9
isort fixup
jbrockmendel Aug 20, 2019
f84258f
type ignore
jbrockmendel Aug 20, 2019
e3c07dd
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 3, 2019
cc36fd7
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 5, 2019
3d96ed6
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 9, 2019
66fd7cc
add str type
jbrockmendel Sep 9, 2019
f994a3b
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 15, 2019
96d4adb
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 16, 2019
85fb1c1
lint fixup
jbrockmendel Sep 16, 2019
ddc056e
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 18, 2019
6947bc0
blackify
jbrockmendel Sep 18, 2019
31e1ed2
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 23, 2019
7e7064c
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 26, 2019
69e349e
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 26, 2019
23ceb47
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Sep 28, 2019
434686c
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Oct 6, 2019
7e98119
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Oct 6, 2019
d5caf5e
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Oct 8, 2019
109699e
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Oct 24, 2019
6136486
Merge branch 'master' of https://github.com/pandas-dev/pandas into opcom
jbrockmendel Nov 14, 2019
bc2c0d5
rename unpack_and_defer -> unpack_zerodim_and_defer
jbrockmendel Nov 14, 2019
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
9 changes: 4 additions & 5 deletions pandas/core/arrays/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from pandas._config import get_option

from pandas._libs import algos as libalgos, hashtable as htable, lib
from pandas._libs import algos as libalgos, hashtable as htable
from pandas.compat.numpy import function as nv
from pandas.util._decorators import (
Appender,
Expand Down Expand Up @@ -39,7 +39,7 @@
needs_i8_conversion,
)
from pandas.core.dtypes.dtypes import CategoricalDtype
from pandas.core.dtypes.generic import ABCDataFrame, ABCIndexClass, ABCSeries
from pandas.core.dtypes.generic import ABCIndexClass, ABCSeries
from pandas.core.dtypes.inference import is_hashable
from pandas.core.dtypes.missing import isna, notna

Expand All @@ -52,6 +52,7 @@
import pandas.core.common as com
from pandas.core.construction import array, extract_array, sanitize_array
from pandas.core.missing import interpolate_2d
from pandas.core.ops.common import unpack_zerodim_and_defer
from pandas.core.sorting import nargsort

from pandas.io.formats import console
Expand All @@ -74,16 +75,14 @@
def _cat_compare_op(op):
opname = "__{op}__".format(op=op.__name__)

@unpack_zerodim_and_defer(opname)
def f(self, other):
# On python2, you can usually compare any type to any type, and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not urgent but if you modify this again would be nice to clean up comment below

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea

# Categoricals can be seen as a custom type, but having different
# results depending whether categories are the same or not is kind of
# insane, so be a bit stricter here and use the python3 idea of
# comparing only things of equal type.
if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
return NotImplemented

other = lib.item_from_zerodim(other)
if is_list_like(other) and len(other) != len(self):
# TODO: Could this fail if the categories are listlike objects?
raise ValueError("Lengths must match.")
Expand Down
24 changes: 8 additions & 16 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,15 @@
is_unsigned_integer_dtype,
pandas_dtype,
)
from pandas.core.dtypes.generic import (
ABCDataFrame,
ABCIndexClass,
ABCPeriodArray,
ABCSeries,
)
from pandas.core.dtypes.generic import ABCIndexClass, ABCPeriodArray, ABCSeries
from pandas.core.dtypes.inference import is_array_like
from pandas.core.dtypes.missing import is_valid_nat_for_dtype, isna

from pandas._typing import DatetimeLikeScalar
from pandas.core import missing, nanops
from pandas.core.algorithms import checked_add_with_arr, take, unique1d, value_counts
import pandas.core.common as com
from pandas.core.ops.common import unpack_zerodim_and_defer
from pandas.core.ops.invalid import make_invalid_op

from pandas.tseries import frequencies
Expand Down Expand Up @@ -1194,13 +1190,11 @@ def _time_shift(self, periods, freq=None):
# to be passed explicitly.
return self._generate_range(start=start, end=end, periods=None, freq=self.freq)

@unpack_zerodim_and_defer("__add__")
def __add__(self, other):
other = lib.item_from_zerodim(other)
if isinstance(other, (ABCSeries, ABCDataFrame, ABCIndexClass)):
return NotImplemented

# scalar others
elif other is NaT:
if other is NaT:
result = self._add_nat()
elif isinstance(other, (Tick, timedelta, np.timedelta64)):
result = self._add_delta(other)
Expand Down Expand Up @@ -1248,13 +1242,11 @@ def __radd__(self, other):
# alias for __add__
return self.__add__(other)

@unpack_zerodim_and_defer("__sub__")
def __sub__(self, other):
other = lib.item_from_zerodim(other)
if isinstance(other, (ABCSeries, ABCDataFrame, ABCIndexClass)):
return NotImplemented

# scalar others
elif other is NaT:
if other is NaT:
result = self._sub_nat()
elif isinstance(other, (Tick, timedelta, np.timedelta64)):
result = self._add_delta(-other)
Expand Down Expand Up @@ -1343,11 +1335,11 @@ def __rsub__(self, other):
return -(self - other)

# FIXME: DTA/TDA/PA inplace methods should actually be inplace, GH#24115
def __iadd__(self, other):
def __iadd__(self, other): # type: ignore
# alias for __add__
return self.__add__(other)

def __isub__(self, other):
def __isub__(self, other): # type: ignore
# alias for __sub__
return self.__sub__(other)

Expand Down
13 changes: 3 additions & 10 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,15 @@
pandas_dtype,
)
from pandas.core.dtypes.dtypes import DatetimeTZDtype
from pandas.core.dtypes.generic import (
ABCDataFrame,
ABCIndexClass,
ABCPandasArray,
ABCSeries,
)
from pandas.core.dtypes.generic import ABCIndexClass, ABCPandasArray, ABCSeries
from pandas.core.dtypes.missing import isna

from pandas.core import ops
from pandas.core.algorithms import checked_add_with_arr
from pandas.core.arrays import datetimelike as dtl
from pandas.core.arrays._ranges import generate_regular_range
import pandas.core.common as com
from pandas.core.ops.common import unpack_zerodim_and_defer
from pandas.core.ops.invalid import invalid_comparison

from pandas.tseries.frequencies import get_period_alias, to_offset
Expand Down Expand Up @@ -157,11 +153,8 @@ def _dt_array_cmp(cls, op):
opname = "__{name}__".format(name=op.__name__)
nat_result = opname == "__ne__"

@unpack_zerodim_and_defer(opname)
def wrapper(self, other):
if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
return NotImplemented

other = lib.item_from_zerodim(other)

if isinstance(other, (datetime, np.datetime64, str)):
if isinstance(other, (datetime, np.datetime64)):
Expand Down
18 changes: 6 additions & 12 deletions pandas/core/arrays/integer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
is_scalar,
)
from pandas.core.dtypes.dtypes import register_extension_dtype
from pandas.core.dtypes.generic import ABCDataFrame, ABCIndexClass, ABCSeries
from pandas.core.dtypes.missing import isna, notna

from pandas.core import nanops, ops
from pandas.core.algorithms import take
from pandas.core.arrays import ExtensionArray, ExtensionOpsMixin
from pandas.core.ops.common import unpack_zerodim_and_defer
from pandas.core.tools.numeric import to_numeric


Expand Down Expand Up @@ -602,13 +602,8 @@ def _values_for_argsort(self) -> np.ndarray:
def _create_comparison_method(cls, op):
op_name = op.__name__

@unpack_zerodim_and_defer(op.__name__)
def cmp_method(self, other):

if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
# Rely on pandas to unbox and dispatch to us.
return NotImplemented

other = lib.item_from_zerodim(other)
mask = None

if isinstance(other, IntegerArray):
Expand Down Expand Up @@ -697,15 +692,14 @@ def _maybe_mask_result(self, result, mask, other, op_name):
def _create_arithmetic_method(cls, op):
op_name = op.__name__

@unpack_zerodim_and_defer(op.__name__)
def integer_arithmetic_method(self, other):

if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
# Rely on pandas to unbox and dispatch to us.
return NotImplemented

other = lib.item_from_zerodim(other)
mask = None

if getattr(other, "ndim", 0) > 1:
raise NotImplementedError("can only perform ops with 1-d structures")

if isinstance(other, IntegerArray):
other, mask = other._data, other._mask

Expand Down
8 changes: 2 additions & 6 deletions pandas/core/arrays/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import numpy as np

from pandas._libs import lib
from pandas._libs.tslibs import (
NaT,
NaTType,
Expand Down Expand Up @@ -35,7 +34,6 @@
)
from pandas.core.dtypes.dtypes import PeriodDtype
from pandas.core.dtypes.generic import (
ABCDataFrame,
ABCIndexClass,
ABCPeriodArray,
ABCPeriodIndex,
Expand All @@ -46,6 +44,7 @@
import pandas.core.algorithms as algos
from pandas.core.arrays import datetimelike as dtl
import pandas.core.common as com
from pandas.core.ops.common import unpack_zerodim_and_defer

from pandas.tseries import frequencies
from pandas.tseries.offsets import DateOffset, Tick, _delta_to_tick
Expand All @@ -69,13 +68,10 @@ def _period_array_cmp(cls, op):
opname = "__{name}__".format(name=op.__name__)
nat_result = opname == "__ne__"

@unpack_zerodim_and_defer(opname)
def wrapper(self, other):
ordinal_op = getattr(self.asi8, opname)

other = lib.item_from_zerodim(other)
if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
return NotImplemented

if is_list_like(other) and len(other) != len(self):
raise ValueError("Lengths must match")

Expand Down
19 changes: 4 additions & 15 deletions pandas/core/arrays/sparse/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@
is_string_dtype,
pandas_dtype,
)
from pandas.core.dtypes.generic import (
ABCDataFrame,
ABCIndexClass,
ABCSeries,
ABCSparseArray,
)
from pandas.core.dtypes.generic import ABCIndexClass, ABCSeries, ABCSparseArray
from pandas.core.dtypes.missing import isna, na_value_for_dtype, notna

import pandas.core.algorithms as algos
Expand All @@ -49,6 +44,7 @@
from pandas.core.construction import sanitize_array
from pandas.core.missing import interpolate_2d
import pandas.core.ops as ops
from pandas.core.ops.common import unpack_zerodim_and_defer

import pandas.io.formats.printing as printing

Expand Down Expand Up @@ -1410,12 +1406,8 @@ def sparse_unary_method(self):
def _create_arithmetic_method(cls, op):
op_name = op.__name__

@unpack_zerodim_and_defer(op_name)
def sparse_arithmetic_method(self, other):
if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
# Rely on pandas to dispatch to us.
return NotImplemented

other = lib.item_from_zerodim(other)

if isinstance(other, SparseArray):
return _sparse_array_op(self, other, op, op_name)
Expand Down Expand Up @@ -1463,12 +1455,9 @@ def _create_comparison_method(cls, op):
if op_name in {"and_", "or_"}:
op_name = op_name[:-1]

@unpack_zerodim_and_defer(op_name)
def cmp_method(self, other):

if isinstance(other, (ABCSeries, ABCIndexClass)):
# Rely on pandas to unbox and dispatch to us.
return NotImplemented

if not is_scalar(other) and not isinstance(other, type(self)):
# convert list-like to ndarray
other = np.asarray(other)
Expand Down
5 changes: 2 additions & 3 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from pandas.core import nanops
from pandas.core.algorithms import checked_add_with_arr
import pandas.core.common as com
from pandas.core.ops.common import unpack_zerodim_and_defer
from pandas.core.ops.invalid import invalid_comparison

from pandas.tseries.frequencies import to_offset
Expand Down Expand Up @@ -82,10 +83,8 @@ def _td_array_cmp(cls, op):
opname = "__{name}__".format(name=op.__name__)
nat_result = opname == "__ne__"

@unpack_zerodim_and_defer(opname)
def wrapper(self, other):
other = lib.item_from_zerodim(other)
if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
return NotImplemented

if _is_convertible_to_td(other) or other is NaT:
try:
Expand Down
11 changes: 5 additions & 6 deletions pandas/core/indexes/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
is_scalar,
is_timedelta64_dtype,
)
from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries, ABCTimedeltaIndex
from pandas.core.dtypes.generic import ABCTimedeltaIndex

from pandas.core import ops
import pandas.core.common as com
from pandas.core.construction import extract_array
import pandas.core.indexes.base as ibase
from pandas.core.indexes.base import Index, _index_shared_docs
from pandas.core.indexes.numeric import Int64Index
from pandas.core.ops.common import unpack_zerodim_and_defer

from pandas.io.formats.printing import pprint_thing

Expand Down Expand Up @@ -734,9 +735,8 @@ def __getitem__(self, key):
# fall back to Int64Index
return super().__getitem__(key)

@unpack_zerodim_and_defer("__floordiv__")
def __floordiv__(self, other):
if isinstance(other, (ABCSeries, ABCDataFrame)):
return NotImplemented

if is_integer(other) and other != 0:
if len(self) == 0 or self.start % other == 0 and self.step % other == 0:
Expand Down Expand Up @@ -772,10 +772,9 @@ def _make_evaluate_binop(op, step=False):
if False, use the existing step
"""

@unpack_zerodim_and_defer(op.__name__)
def _evaluate_numeric_binop(self, other):
if isinstance(other, (ABCSeries, ABCDataFrame)):
return NotImplemented
elif isinstance(other, ABCTimedeltaIndex):
if isinstance(other, ABCTimedeltaIndex):
# Defer to TimedeltaIndex implementation
return NotImplemented
elif isinstance(other, (timedelta, np.timedelta64)):
Expand Down
14 changes: 4 additions & 10 deletions pandas/core/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
logical_op,
)
from pandas.core.ops.array_ops import comp_method_OBJECT_ARRAY # noqa:F401
from pandas.core.ops.common import unpack_zerodim_and_defer
from pandas.core.ops.dispatch import maybe_dispatch_ufunc_to_dunder_op # noqa:F401
from pandas.core.ops.dispatch import should_series_dispatch
from pandas.core.ops.docstrings import (
Expand Down Expand Up @@ -489,9 +490,8 @@ def _arith_method_SERIES(cls, op, special):
op_name = _get_op_name(op, special)
eval_kwargs = _gen_eval_kwargs(op_name)

@unpack_zerodim_and_defer(op_name)
def wrapper(left, right):
if isinstance(right, ABCDataFrame):
return NotImplemented

left, right = _align_method_SERIES(left, right)
res_name = get_op_result_name(left, right)
Expand All @@ -512,14 +512,11 @@ def _comp_method_SERIES(cls, op, special):
"""
op_name = _get_op_name(op, special)

@unpack_zerodim_and_defer(op_name)
def wrapper(self, other):

res_name = get_op_result_name(self, other)

if isinstance(other, ABCDataFrame): # pragma: no cover
# Defer to DataFrame implementation; fail early
return NotImplemented

if isinstance(other, ABCSeries) and not self._indexed_same(other):
raise ValueError("Can only compare identically-labeled Series objects")

Expand All @@ -541,14 +538,11 @@ def _bool_method_SERIES(cls, op, special):
"""
op_name = _get_op_name(op, special)

@unpack_zerodim_and_defer(op_name)
def wrapper(self, other):
self, other = _align_method_SERIES(self, other, align_asobject=True)
res_name = get_op_result_name(self, other)

if isinstance(other, ABCDataFrame):
# Defer to DataFrame implementation; fail early
return NotImplemented

lvalues = extract_array(self, extract_numpy=True)
rvalues = extract_array(other, extract_numpy=True)

Expand Down
Loading