From 38737d443797d5647fbd4ff917ab4d28c089ea11 Mon Sep 17 00:00:00 2001 From: Jim Crist-Harif Date: Tue, 10 Sep 2024 12:56:01 -0500 Subject: [PATCH] depr(api): deprecate `bool_val.negate()`/`-bool_val` in favor of `~bool_val` --- ibis/backends/tests/sql/test_sql.py | 4 +-- ibis/backends/tests/test_aggregation.py | 4 +-- ibis/backends/tests/test_generic.py | 8 +++--- ibis/expr/types/logical.py | 35 +++++++------------------ ibis/tests/expr/test_value_exprs.py | 10 +++---- 5 files changed, 20 insertions(+), 41 deletions(-) diff --git a/ibis/backends/tests/sql/test_sql.py b/ibis/backends/tests/sql/test_sql.py index 81f2b57e6a8f6..bca6f56578f9b 100644 --- a/ibis/backends/tests/sql/test_sql.py +++ b/ibis/backends/tests/sql/test_sql.py @@ -173,7 +173,7 @@ def test_isnull_notnull(functional_alltypes, method_name, snapshot): def test_negate(functional_alltypes, snapshot): - expr = -(functional_alltypes.double_col > 0) + expr = ~(functional_alltypes.double_col > 0) snapshot.assert_match(to_sql(expr.name("tmp")), "out.sql") @@ -319,7 +319,7 @@ def test_self_reference_in_not_exists(functional_alltypes, snapshot): cond = (t.string_col == t2.string_col).any() semi = t.filter(cond) - anti = t.filter(-cond) + anti = t.filter(~cond) snapshot.assert_match(to_sql(semi), "semi.sql") snapshot.assert_match(to_sql(anti), "anti.sql") diff --git a/ibis/backends/tests/test_aggregation.py b/ibis/backends/tests/test_aggregation.py index 19e1207ee405e..2499355b12e01 100644 --- a/ibis/backends/tests/test_aggregation.py +++ b/ibis/backends/tests/test_aggregation.py @@ -294,7 +294,7 @@ def mean_and_std(v): ], ), param( - lambda t, where: -t.bool_col.any(where=where), + lambda t, where: ~t.bool_col.any(where=where), lambda t, where: ~t.bool_col[where].any(), id="any_negate", marks=[ @@ -330,7 +330,7 @@ def mean_and_std(v): ], ), param( - lambda t, where: -t.bool_col.all(where=where), + lambda t, where: ~t.bool_col.all(where=where), lambda t, where: ~t.bool_col[where].all(), id="all_negate", marks=[ diff --git a/ibis/backends/tests/test_generic.py b/ibis/backends/tests/test_generic.py index 23f5d83fdd924..94fbd8ac1d432 100644 --- a/ibis/backends/tests/test_generic.py +++ b/ibis/backends/tests/test_generic.py @@ -5,7 +5,7 @@ import decimal from collections import Counter from itertools import permutations -from operator import invert, methodcaller, neg +from operator import invert, methodcaller import pytest import toolz @@ -76,7 +76,7 @@ def test_null_literal_typed(con, backend): expr = ibis.null(bool) assert expr.type() == dt.boolean assert pd.isna(con.execute(expr)) - assert pd.isna(con.execute(expr.negate())) + assert pd.isna(con.execute(~expr)) assert pd.isna(con.execute(expr.cast(str).upper())) @@ -1003,15 +1003,13 @@ def test_isin_notin_column_expr(backend, alltypes, df, ibis_op, pandas_op): param(False, False, toolz.identity, id="false_noop"), param(True, False, invert, id="true_invert"), param(False, True, invert, id="false_invert"), - param(True, False, neg, id="true_negate"), - param(False, True, neg, id="false_negate"), ], ) def test_logical_negation_literal(con, expr, expected, op): assert con.execute(op(ibis.literal(expr)).name("tmp")) == expected -@pytest.mark.parametrize("op", [toolz.identity, invert, neg]) +@pytest.mark.parametrize("op", [toolz.identity, invert]) def test_logical_negation_column(backend, alltypes, df, op): result = op(alltypes["bool_col"]).name("tmp").execute() expected = op(df["bool_col"]) diff --git a/ibis/expr/types/logical.py b/ibis/expr/types/logical.py index a1dace11dfea5..306203c08a6ba 100644 --- a/ibis/expr/types/logical.py +++ b/ibis/expr/types/logical.py @@ -6,6 +6,7 @@ import ibis import ibis.expr.operations as ops +from ibis import util from ibis.expr.types.core import _binop from ibis.expr.types.numeric import NumericColumn, NumericScalar, NumericValue @@ -227,34 +228,16 @@ def __invert__(self) -> BooleanValue: │ NULL │ └──────────┘ """ - return self.negate() + return ops.Not(self).to_expr() def negate(self) -> BooleanValue: - """Negate a boolean expression. - - Returns - ------- - BooleanValue - A boolean value expression - - Examples - -------- - >>> import ibis - >>> ibis.options.interactive = True - >>> t = ibis.memtable({"values": [True, False, False, None]}) - >>> t.values.negate() - ┏━━━━━━━━━━━━━┓ - ┃ Not(values) ┃ - ┡━━━━━━━━━━━━━┩ - │ boolean │ - ├─────────────┤ - │ False │ - │ True │ - │ True │ - │ NULL │ - └─────────────┘ - """ - return ops.Not(self).to_expr() + """DEPRECATED.""" + util.warn_deprecated( + "`-bool_val`/`bool_val.negate()`", + instead="use `~bool_val` instead", + as_of="9.5", + ) + return ~self @public diff --git a/ibis/tests/expr/test_value_exprs.py b/ibis/tests/expr/test_value_exprs.py index e95bda04d864e..35a376ffc3ab8 100644 --- a/ibis/tests/expr/test_value_exprs.py +++ b/ibis/tests/expr/test_value_exprs.py @@ -501,17 +501,15 @@ def test_negate(table, col): assert isinstance(result.op(), ops.Negate) -@pytest.mark.parametrize("op", [operator.neg, operator.invert]) @pytest.mark.parametrize("value", [True, False]) -def test_negate_boolean_scalar(op, value): - result = op(ibis.literal(value)) +def test_negate_boolean_scalar(value): + result = ~ibis.literal(value) assert isinstance(result, ir.BooleanScalar) assert isinstance(result.op(), ops.Not) -@pytest.mark.parametrize("op", [operator.neg, operator.invert]) -def test_negate_boolean_column(table, op): - result = op(table["h"]) +def test_negate_boolean_column(table): + result = ~table["h"] assert isinstance(result, ir.BooleanColumn) assert isinstance(result.op(), ops.Not)