From 4664afe33c33e30b4488e180aadc81f4a02c74cc Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 27 Apr 2021 10:43:59 +0200 Subject: [PATCH 1/3] TST: run frame/series arithmetic tests with+without numexpr --- pandas/tests/frame/test_arithmetic.py | 24 +++++++++++++++++++++++- pandas/tests/series/test_arithmetic.py | 11 +++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_arithmetic.py b/pandas/tests/frame/test_arithmetic.py index 4c31d15541412..eaf1c64be08db 100644 --- a/pandas/tests/frame/test_arithmetic.py +++ b/pandas/tests/frame/test_arithmetic.py @@ -17,6 +17,7 @@ ) import pandas._testing as tm import pandas.core.common as com +from pandas.core.computation import expressions as expr from pandas.core.computation.expressions import ( _MIN_ELEMENTS, NUMEXPR_INSTALLED, @@ -27,6 +28,16 @@ ) +@pytest.fixture( + autouse=True, scope="module", params=[0, 1000000], ids=["numexpr", "python"] +) +def switch_numexpr_min_elements(request): + _MIN_ELEMENTS = expr._MIN_ELEMENTS + expr._MIN_ELEMENTS = request.param + yield request.param + expr._MIN_ELEMENTS = _MIN_ELEMENTS + + class DummyElement: def __init__(self, value, dtype): self.value = value @@ -514,7 +525,12 @@ def f(x, y): @pytest.mark.parametrize("op", ["__add__", "__sub__", "__mul__"]) def test_arith_flex_frame_mixed( - self, op, int_frame, mixed_int_frame, mixed_float_frame + self, + op, + int_frame, + mixed_int_frame, + mixed_float_frame, + switch_numexpr_min_elements, ): f = getattr(operator, op) @@ -528,6 +544,12 @@ def test_arith_flex_frame_mixed( dtype = {"B": "uint64", "C": None} elif op in ["__add__", "__mul__"]: dtype = {"C": None} + if expr.USE_NUMEXPR and switch_numexpr_min_elements == 0: + # when using numexpr, the casting rules are slightly different: + # in the `2 + mixed_int_frame` operation, int32 column becomes + # and int64 column (not preserving dtype in operation with Python + # scalar), and then the int32/int64 combo results in int64 result + dtype["A"] = "int64" tm.assert_frame_equal(result, expected) _check_mixed_int(result, dtype=dtype) diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 0b6939a0997a4..72b6b7527f57f 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -28,6 +28,17 @@ nanops, ops, ) +from pandas.core.computation import expressions as expr + + +@pytest.fixture( + autouse=True, scope="module", params=[0, 1000000], ids=["numexpr", "python"] +) +def switch_numexpr_min_elements(request): + _MIN_ELEMENTS = expr._MIN_ELEMENTS + expr._MIN_ELEMENTS = request.param + yield request.param + expr._MIN_ELEMENTS = _MIN_ELEMENTS def _permute(obj): From 8cb686ed71fd1344c8a87637bfbff07e0e2d0cc4 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 27 Apr 2021 11:41:36 +0200 Subject: [PATCH 2/3] make robust for 32bit os --- pandas/tests/frame/test_arithmetic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_arithmetic.py b/pandas/tests/frame/test_arithmetic.py index eaf1c64be08db..57e666a122fb0 100644 --- a/pandas/tests/frame/test_arithmetic.py +++ b/pandas/tests/frame/test_arithmetic.py @@ -549,7 +549,7 @@ def test_arith_flex_frame_mixed( # in the `2 + mixed_int_frame` operation, int32 column becomes # and int64 column (not preserving dtype in operation with Python # scalar), and then the int32/int64 combo results in int64 result - dtype["A"] = "int64" + dtype["A"] = (2 + mixed_int_frame)["A"].dtype tm.assert_frame_equal(result, expected) _check_mixed_int(result, dtype=dtype) From b1cbe9c8963d737fd05697aaf2d1d9ffe2da1f4f Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Wed, 28 Apr 2021 12:26:32 +0200 Subject: [PATCH 3/3] test boolean op warning for numexpr --- pandas/tests/frame/test_arithmetic.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pandas/tests/frame/test_arithmetic.py b/pandas/tests/frame/test_arithmetic.py index 77c1bc7f25ff3..3c8941c6361e0 100644 --- a/pandas/tests/frame/test_arithmetic.py +++ b/pandas/tests/frame/test_arithmetic.py @@ -914,7 +914,7 @@ def test_frame_with_frame_reindex(self): ], ids=lambda x: x.__name__, ) - def test_binop_other(self, op, value, dtype): + def test_binop_other(self, op, value, dtype, switch_numexpr_min_elements): skip = { (operator.truediv, "bool"), @@ -963,11 +963,13 @@ def test_binop_other(self, op, value, dtype): elif (op, dtype) in skip: if op in [operator.add, operator.mul]: - # TODO we should assert this or not depending on whether - # numexpr is used or not - # with tm.assert_produces_warning(UserWarning): - # # "evaluating in Python space because ..." - op(s, e.value) + if expr.USE_NUMEXPR and switch_numexpr_min_elements == 0: + # "evaluating in Python space because ..." + warn = UserWarning + else: + warn = None + with tm.assert_produces_warning(warn): + op(s, e.value) else: msg = "operator '.*' not implemented for .* dtypes"