Skip to content

Commit

Permalink
feat(dask/pandas): raise OperationNotDefinedError exc for not defined…
Browse files Browse the repository at this point in the history
… operations
  • Loading branch information
krzysztof-kwitt authored and cpcloud committed Feb 4, 2023
1 parent 66540eb commit 2833685
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 34 deletions.
5 changes: 3 additions & 2 deletions ibis/backends/dask/tests/execution/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import ibis
import ibis.expr.datatypes as dt
from ibis.common.exceptions import OperationNotDefinedError

dd = pytest.importorskip("dask.dataframe")
from dask.dataframe.utils import tm # noqa: E402
Expand Down Expand Up @@ -142,7 +143,7 @@ def test_round_decimal_with_negative_places(t, df):


@pytest.mark.xfail(
raises=NotImplementedError,
raises=OperationNotDefinedError,
reason='TODO - arrays - #2553'
# Need an ops.MultiQuantile execution func that dispatches on ndarrays
)
Expand Down Expand Up @@ -202,7 +203,7 @@ def test_arraylike_functions_transform_errors(t, df, ibis_func, exc):


@pytest.mark.xfail(
raises=NotImplementedError,
raises=OperationNotDefinedError,
reason='TODO - arrays - #2553'
# Need an ops.MultiQuantile execution func that dispatches on ndarrays
)
Expand Down
3 changes: 2 additions & 1 deletion ibis/backends/dask/tests/execution/test_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import ibis
import ibis.expr.datatypes as dt
from ibis.common.exceptions import OperationNotDefinedError

da = pytest.importorskip("dask.array")
dd = pytest.importorskip("dask.dataframe")
Expand Down Expand Up @@ -818,7 +819,7 @@ def test_round(t, df):


@pytest.mark.xfail(
raises=NotImplementedError,
raises=OperationNotDefinedError,
reason="MultiQuantile is not implemented for the dask backend",
)
def test_quantile_group_by(batting, batting_df):
Expand Down
6 changes: 3 additions & 3 deletions ibis/backends/dask/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def table(self, name):
con = MyBackend()
t = con.table('t')
with pytest.raises(
NotImplementedError,
match='Could not find signature for execute_node: <DatabaseTable, MyBackend>',
com.OperationNotDefinedError,
match="Operation 'DatabaseTable' is not implemented for this backend",
):
con.execute(t)

Expand Down Expand Up @@ -112,4 +112,4 @@ def test_scope_look_up():
def test_new_dispatcher():
types = (ops.TableColumn, dd.DataFrame)
assert execute_node.dispatch(*types) is not None
assert pandas_execute_node.dispatch(*types) is None
assert pandas_execute_node.dispatch(*types).__name__ == 'raise_unknown_op'
6 changes: 3 additions & 3 deletions ibis/backends/pandas/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
)


@execute_node.register(ops.Node)
def raise_unknown_op(node, **kwargs):
raise NotImplementedError(
@execute_node.register(ops.Node, [object])
def raise_unknown_op(node, *args, **kwargs):
raise com.OperationNotDefinedError(
f"Operation {type(node).__name__!r} is not implemented for this backend"
)

Expand Down
3 changes: 2 additions & 1 deletion ibis/backends/pandas/execution/decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import ibis.expr.datatypes as dt
import ibis.expr.operations as ops
from ibis.backends.pandas.dispatch import execute_node
from ibis.common.exceptions import OperationNotDefinedError


@execute_node.register(ops.Ln, decimal.Decimal)
Expand Down Expand Up @@ -66,7 +67,7 @@ def execute_decimal_unary(op, data, **kwargs):
if function is None:
math_function = getattr(math, operation_name, None)
if math_function is None:
raise NotImplementedError(f'{op_type.__name__} not supported')
raise OperationNotDefinedError(f'{op_type.__name__} not supported')
function = lambda x: decimal.Decimal(math_function(x))
try:
return function(data)
Expand Down
4 changes: 2 additions & 2 deletions ibis/backends/pandas/execution/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def call_numpy_ufunc(func, op, data, **kwargs):
if getattr(data, "dtype", None) == np.dtype(np.object_):
return data.apply(functools.partial(execute_node, op, **kwargs))
if func is None:
raise NotImplementedError(f'{type(op).__name__} not supported')
raise com.OperationNotDefinedError(f'{type(op).__name__} not supported')
return func(data)


Expand Down Expand Up @@ -888,7 +888,7 @@ def _execute_binary_op_impl(op, left, right, **_):
try:
operation = constants.BINARY_OPERATIONS[op_type]
except KeyError:
raise NotImplementedError(
raise com.OperationNotDefinedError(
f'Binary operation {op_type.__name__} not implemented'
)
else:
Expand Down
3 changes: 2 additions & 1 deletion ibis/backends/pandas/execution/join.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ibis.backends.pandas.core import execute
from ibis.backends.pandas.dispatch import execute_node
from ibis.backends.pandas.execution import constants
from ibis.common.exceptions import UnsupportedOperationError


def _compute_join_column(column, **kwargs):
Expand Down Expand Up @@ -102,7 +103,7 @@ def execute_join(op, left, right, predicates, **kwargs):
try:
how = constants.JOIN_TYPES[op_type]
except KeyError:
raise NotImplementedError(f'{op_type.__name__} not supported')
raise UnsupportedOperationError(f'{op_type.__name__} not supported')

left_on, right_on = _construct_join_predicate_columns(op, predicates, **kwargs)

Expand Down
5 changes: 3 additions & 2 deletions ibis/backends/pandas/tests/execution/test_cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import ibis.expr.datatypes as dt
from ibis.backends.pandas.execution import execute
from ibis.backends.pandas.tests.conftest import TestConf as tm
from ibis.common.exceptions import OperationNotDefinedError

TIMESTAMP = "2022-03-13 06:59:10.467417"

Expand Down Expand Up @@ -97,7 +98,7 @@ def test_cast_timestamp_column(t, df, column, to, expected):
param(
'double',
float,
marks=pytest.mark.xfail(raises=NotImplementedError),
marks=pytest.mark.xfail(raises=OperationNotDefinedError),
),
(
dt.Timestamp('America/Los_Angeles'),
Expand All @@ -121,7 +122,7 @@ def test_cast_timestamp_scalar_naive(to, expected):
param(
'double',
float,
marks=pytest.mark.xfail(raises=NotImplementedError),
marks=pytest.mark.xfail(raises=OperationNotDefinedError),
),
(
dt.Timestamp('America/Los_Angeles'),
Expand Down
4 changes: 2 additions & 2 deletions ibis/backends/pandas/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ def table(self, name):
con = MyBackend()
t = con.table('t')
with pytest.raises(
NotImplementedError,
match=('Could not find signature for execute_node: <DatabaseTable, MyBackend>'),
com.OperationNotDefinedError,
match="Operation 'DatabaseTable' is not implemented for this backend",
):
con.execute(t)

Expand Down
12 changes: 6 additions & 6 deletions ibis/backends/polars/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def literal(op):
elif dtype.is_null():
return pl.lit(value)
elif dtype.is_binary():
raise NotImplementedError("Binary literals do not work in polars")
raise NotImplementedError(f"Unsupported type: {dtype!r}")
else:
typ = to_polars_type(dtype)
return pl.lit(op.value, dtype=typ)
Expand Down Expand Up @@ -414,7 +414,7 @@ def string_unary(op):
arg = translate(op.arg)
func = _string_unary.get(type(op))
if func is None:
raise NotImplementedError(f'{type(op).__name__} not supported')
raise com.OperationNotDefinedError(f'{type(op).__name__} not supported')

method = getattr(arg.str, func)
return method()
Expand Down Expand Up @@ -881,7 +881,7 @@ def unary(op):
arg = translate(op.arg)
func = _unary.get(type(op))
if func is None:
raise NotImplementedError(f'{type(op).__name__} not supported')
raise com.OperationNotDefinedError(f'{type(op).__name__} not supported')
return func(arg)


Expand All @@ -901,7 +901,7 @@ def comparison(op):
right = translate(op.right)
func = _comparisons.get(type(op))
if func is None:
raise NotImplementedError(f'{type(op).__name__} not supported')
raise com.OperationNotDefinedError(f'{type(op).__name__} not supported')
return func(left, right)


Expand All @@ -928,7 +928,7 @@ def between(op):
def bitwise_binops(op):
ufunc = _bitwise_binops.get(type(op))
if ufunc is None:
raise NotImplementedError(f'{type(op).__name__} not supported')
raise com.OperationNotDefinedError(f'{type(op).__name__} not supported')
left = translate(op.left)
right = translate(op.right)

Expand Down Expand Up @@ -968,7 +968,7 @@ def binop(op):
right = translate(op.right)
func = _binops.get(type(op))
if func is None:
raise NotImplementedError(f'{type(op).__name__} not supported')
raise com.OperationNotDefinedError(f'{type(op).__name__} not supported')
return func(left, right)


Expand Down
4 changes: 1 addition & 3 deletions ibis/backends/polars/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ def to_polars_type(dtype):
try:
return _to_polars_types[dtype.__class__] # else return pl.Object?
except KeyError:
raise NotImplementedError(
f"Translation to polars dtype not implemented for {dtype}"
)
raise NotImplementedError(f"Unsupported type: {dtype!r}")


@to_polars_type.register(dt.Timestamp)
Expand Down
5 changes: 4 additions & 1 deletion ibis/backends/pyarrow/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@

@functools.singledispatch
def to_pyarrow_type(dtype: dt.DataType):
return _to_pyarrow_types[dtype.__class__]
arrow_type = _to_pyarrow_types.get(dtype.__class__)
if not arrow_type:
raise NotImplementedError(f'Unsupported type: {dtype!r}')
return arrow_type


@to_pyarrow_type.register(dt.Array)
Expand Down
Loading

0 comments on commit 2833685

Please sign in to comment.