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

Properly implement binaryops for proxy types #15684

Merged
merged 8 commits into from
May 8, 2024
224 changes: 196 additions & 28 deletions python/cudf/cudf/pandas/fast_slow_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,88 +598,256 @@ def __setattr__(self, name, value):
return _FastSlowAttribute("__setattr__").__get__(self)(name, value)

def __add__(self, other):
galipremsagar marked this conversation as resolved.
Show resolved Hide resolved
return _fast_slow_function_call(operator.add, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__add__(y)
if hasattr(x, "__add__")
else NotImplemented,
self,
other,
)[0]

def __radd__(self, other):
return _fast_slow_function_call(operator.add, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__radd__(y)
if hasattr(x, "__radd__")
else NotImplemented,
self,
other,
)[0]

def __sub__(self, other):
return _fast_slow_function_call(operator.sub, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__sub__(y)
if hasattr(x, "__sub__")
else NotImplemented,
self,
other,
)[0]

def __rsub__(self, other):
return _fast_slow_function_call(operator.sub, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rsub__(y)
if hasattr(x, "__rsub__")
else NotImplemented,
self,
other,
)[0]

def __mul__(self, other):
return _fast_slow_function_call(operator.mul, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__mul__(y)
if hasattr(x, "__mul__")
else NotImplemented,
self,
other,
)[0]

def __rmul__(self, other):
return _fast_slow_function_call(operator.mul, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rmul__(y)
if hasattr(x, "__rmul__")
else NotImplemented,
self,
other,
)[0]

def __truediv__(self, other):
return _fast_slow_function_call(operator.truediv, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__truediv__(y)
if hasattr(x, "__truediv__")
else NotImplemented,
self,
other,
)[0]

def __rtruediv__(self, other):
return _fast_slow_function_call(operator.truediv, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rtruediv__(y)
if hasattr(x, "__rtruediv__")
else NotImplemented,
self,
other,
)[0]

def __floordiv__(self, other):
return _fast_slow_function_call(operator.floordiv, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__floordiv__(y)
if hasattr(x, "__floordiv__")
else NotImplemented,
self,
other,
)[0]

def __rfloordiv__(self, other):
return _fast_slow_function_call(operator.floordiv, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rfloordiv__(y)
if hasattr(x, "__rfloordiv__")
else NotImplemented,
self,
other,
)[0]

def __mod__(self, other):
return _fast_slow_function_call(operator.mod, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__mod__(y)
if hasattr(x, "__mod__")
else NotImplemented,
self,
other,
)[0]

def __rmod__(self, other):
return _fast_slow_function_call(operator.mod, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rmod__(y)
if hasattr(x, "__rmod__")
else NotImplemented,
self,
other,
)[0]

def __divmod__(self, other):
return _fast_slow_function_call(divmod, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__divmod__(y)
if hasattr(x, "__divmod__")
else NotImplemented,
self,
other,
)[0]

def __rdivmod__(self, other):
return _fast_slow_function_call(divmod, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rdivmod__(y)
if hasattr(x, "__rdivmod__")
else NotImplemented,
self,
other,
)[0]

def __pow__(self, other):
return _fast_slow_function_call(operator.pow, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__pow__(y)
if hasattr(x, "__pow__")
else NotImplemented,
self,
other,
)[0]

def __rpow__(self, other):
return _fast_slow_function_call(operator.pow, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rpow__(y)
if hasattr(x, "__rpow__")
else NotImplemented,
self,
other,
)[0]

def __lshift__(self, other):
return _fast_slow_function_call(operator.lshift, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__lshift__(y)
if hasattr(x, "__lshift__")
else NotImplemented,
self,
other,
)[0]

def __rlshift__(self, other):
return _fast_slow_function_call(operator.lshift, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rlshift__(y)
if hasattr(x, "__rlshift__")
else NotImplemented,
self,
other,
)[0]

def __rshift__(self, other):
return _fast_slow_function_call(operator.rshift, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__rshift__(y)
if hasattr(x, "__rshift__")
else NotImplemented,
self,
other,
)[0]

def __rrshift__(self, other):
return _fast_slow_function_call(operator.rshift, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rrshift__(y)
if hasattr(x, "__rrshift__")
else NotImplemented,
self,
other,
)[0]

def __and__(self, other):
return _fast_slow_function_call(operator.and_, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__and__(y)
if hasattr(x, "__and__")
else NotImplemented,
self,
other,
)[0]

def __rand__(self, other):
return _fast_slow_function_call(operator.and_, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rand__(y)
if hasattr(x, "__rand__")
else NotImplemented,
self,
other,
)[0]

def __xor__(self, other):
return _fast_slow_function_call(operator.xor, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__xor__(y)
if hasattr(x, "__xor__")
else NotImplemented,
self,
other,
)[0]

def __rxor__(self, other):
return _fast_slow_function_call(operator.xor, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rxor__(y)
if hasattr(x, "__rxor__")
else NotImplemented,
self,
other,
)[0]

def __or__(self, other):
return _fast_slow_function_call(operator.or_, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__or__(y)
if hasattr(x, "__or__")
else NotImplemented,
self,
other,
)[0]

def __ror__(self, other):
return _fast_slow_function_call(operator.or_, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__ror__(y)
if hasattr(x, "__ror__")
else NotImplemented,
self,
other,
)[0]

def __matmul__(self, other):
return _fast_slow_function_call(operator.matmul, self, other)[0]
return _fast_slow_function_call(
lambda x, y: x.__matmul__(y)
if hasattr(x, "__matmul__")
else NotImplemented,
self,
other,
)[0]

def __rmatmul__(self, other):
return _fast_slow_function_call(operator.matmul, other, self)[0]
return _fast_slow_function_call(
lambda x, y: x.__rmatmul__(y)
if hasattr(x, "__rmatmul__")
else NotImplemented,
self,
other,
)[0]


class _FinalProxy(_FastSlowProxy):
Expand Down
13 changes: 13 additions & 0 deletions python/cudf/cudf_pandas_tests/test_cudf_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,19 @@ def test_isinstance_base_offset():
assert isinstance(offset, xpd.tseries.offsets.BaseOffset)


def test_floordiv_array_vs_df():
xarray = xpd.Series([1, 2, 3], dtype="datetime64[ns]").array
parray = pd.Series([1, 2, 3], dtype="datetime64[ns]").array

xdf = xpd.DataFrame(xarray)
pdf = pd.DataFrame(parray)

actual = xarray.__floordiv__(xdf)
expected = parray.__floordiv__(pdf)

tm.assert_equal(actual, expected)


def test_apply_slow_path_udf_references_global_module():
def my_apply(df, unused):
# `datetime` Raised `KeyError: __import__`
Expand Down
4 changes: 0 additions & 4 deletions python/cudf/cudf_pandas_tests/test_fast_slow_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,6 @@ def __radd__(self, other):
assert Bar() + Foo() == "sum"
assert FooProxy() + BarProxy() == "sum"
assert BarProxy() + FooProxy() == "sum"
assert FooProxy() + Bar() == "sum"
assert Bar() + FooProxy() == "sum"
assert Foo() + BarProxy() == "sum"
assert BarProxy() + Foo() == "sum"


def test_slow_attr_still_proxy():
Expand Down
Loading