From 2f008a91a68cef1a560b7751afa700faa65ba852 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 15 Mar 2021 11:31:08 +0100 Subject: [PATCH 1/4] REF: move roperators to pandas.core --- pandas/core/ops/__init__.py | 21 +++++---------------- pandas/core/ops/array_ops.py | 11 ++++++----- pandas/core/ops/methods.py | 27 +++++++++------------------ pandas/core/ops/missing.py | 12 ++++-------- pandas/core/{ops => }/roperator.py | 0 5 files changed, 24 insertions(+), 47 deletions(-) rename pandas/core/{ops => }/roperator.py (100%) diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index 8ace64fedacb9..3417411553c05 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -29,7 +29,10 @@ ) from pandas.core.dtypes.missing import isna -from pandas.core import algorithms +from pandas.core import ( + algorithms, + roperator, +) from pandas.core.ops.array_ops import ( # noqa:F401 arithmetic_op, comp_method_OBJECT_ARRAY, @@ -53,20 +56,6 @@ kleene_xor, ) from pandas.core.ops.methods import add_flex_arithmetic_methods # noqa:F401 -from pandas.core.ops.roperator import ( # noqa:F401 - radd, - rand_, - rdiv, - rdivmod, - rfloordiv, - rmod, - rmul, - ror_, - rpow, - rsub, - rtruediv, - rxor, -) if TYPE_CHECKING: from pandas import ( @@ -319,7 +308,7 @@ def should_reindex_frame_op( """ assert isinstance(left, ABCDataFrame) - if op is operator.pow or op is rpow: + if op is operator.pow or op is roperator.rpow: # GH#32685 pow has special semantics for operating with null values return False diff --git a/pandas/core/ops/array_ops.py b/pandas/core/ops/array_ops.py index 9153eb25032e7..8d46602389745 100644 --- a/pandas/core/ops/array_ops.py +++ b/pandas/core/ops/array_ops.py @@ -45,11 +45,14 @@ notna, ) +import pandas.core.computation.expressions as expressions from pandas.core.construction import ensure_wrapped_if_datetimelike -from pandas.core.ops import missing +from pandas.core.ops import ( + missing, + roperator, +) from pandas.core.ops.dispatch import should_extension_dispatch from pandas.core.ops.invalid import invalid_comparison -from pandas.core.ops.roperator import rpow def comp_method_OBJECT_ARRAY(op, x, y): @@ -122,7 +125,7 @@ def _masked_arith_op(x: np.ndarray, y, op): # 1 ** np.nan is 1. So we have to unmask those. if op is pow: mask = np.where(x == 1, False, mask) - elif op is rpow: + elif op is roperator.rpow: mask = np.where(y == 1, False, mask) if mask.any(): @@ -155,8 +158,6 @@ def _na_arithmetic_op(left, right, op, is_cmp: bool = False): ------ TypeError : invalid operation """ - import pandas.core.computation.expressions as expressions - try: result = expressions.evaluate(op, left, right) except TypeError: diff --git a/pandas/core/ops/methods.py b/pandas/core/ops/methods.py index 700c4a946e2b2..df22919ed19f1 100644 --- a/pandas/core/ops/methods.py +++ b/pandas/core/ops/methods.py @@ -8,16 +8,7 @@ ABCSeries, ) -from pandas.core.ops.roperator import ( - radd, - rdivmod, - rfloordiv, - rmod, - rmul, - rpow, - rsub, - rtruediv, -) +from pandas.core.ops import roperator def _get_method_wrappers(cls): @@ -89,19 +80,19 @@ def _create_methods(cls, arith_method, comp_method): new_methods.update( { "add": arith_method(operator.add), - "radd": arith_method(radd), + "radd": arith_method(roperator.radd), "sub": arith_method(operator.sub), "mul": arith_method(operator.mul), "truediv": arith_method(operator.truediv), "floordiv": arith_method(operator.floordiv), "mod": arith_method(operator.mod), "pow": arith_method(operator.pow), - "rmul": arith_method(rmul), - "rsub": arith_method(rsub), - "rtruediv": arith_method(rtruediv), - "rfloordiv": arith_method(rfloordiv), - "rpow": arith_method(rpow), - "rmod": arith_method(rmod), + "rmul": arith_method(roperator.rmul), + "rsub": arith_method(roperator.rsub), + "rtruediv": arith_method(roperator.rtruediv), + "rfloordiv": arith_method(roperator.rfloordiv), + "rpow": arith_method(roperator.rpow), + "rmod": arith_method(roperator.rmod), } ) new_methods["div"] = new_methods["truediv"] @@ -109,7 +100,7 @@ def _create_methods(cls, arith_method, comp_method): if have_divmod: # divmod doesn't have an op that is supported by numexpr new_methods["divmod"] = arith_method(divmod) - new_methods["rdivmod"] = arith_method(rdivmod) + new_methods["rdivmod"] = arith_method(roperator.rdivmod) new_methods.update( { diff --git a/pandas/core/ops/missing.py b/pandas/core/ops/missing.py index 20b7510c33160..ea6223765523d 100644 --- a/pandas/core/ops/missing.py +++ b/pandas/core/ops/missing.py @@ -31,11 +31,7 @@ is_scalar, ) -from pandas.core.ops.roperator import ( - rdivmod, - rfloordiv, - rmod, -) +from pandas.core.ops import roperator def fill_zeros(result, x, y): @@ -167,7 +163,7 @@ def dispatch_fill_zeros(op, left, right, result): mask_zero_div_zero(left, right, result[0]), fill_zeros(result[1], left, right), ) - elif op is rdivmod: + elif op is roperator.rdivmod: result = ( mask_zero_div_zero(right, left, result[0]), fill_zeros(result[1], right, left), @@ -176,12 +172,12 @@ def dispatch_fill_zeros(op, left, right, result): # Note: no need to do this for truediv; in py3 numpy behaves the way # we want. result = mask_zero_div_zero(left, right, result) - elif op is rfloordiv: + elif op is roperator.rfloordiv: # Note: no need to do this for rtruediv; in py3 numpy behaves the way # we want. result = mask_zero_div_zero(right, left, result) elif op is operator.mod: result = fill_zeros(result, left, right) - elif op is rmod: + elif op is roperator.rmod: result = fill_zeros(result, right, left) return result diff --git a/pandas/core/ops/roperator.py b/pandas/core/roperator.py similarity index 100% rename from pandas/core/ops/roperator.py rename to pandas/core/roperator.py From 959618ded110f0d634bebdd437315ab96b9b1ecb Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 16 Mar 2021 11:54:09 +0100 Subject: [PATCH 2/4] add back imports in ops --- pandas/core/ops/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index 3417411553c05..4ebcd6533af2e 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -56,6 +56,20 @@ kleene_xor, ) from pandas.core.ops.methods import add_flex_arithmetic_methods # noqa:F401 +from pandas.core.roperator import ( # noqa:F401 + radd, + rand_, + rdiv, + rdivmod, + rfloordiv, + rmod, + rmul, + ror_, + rpow, + rsub, + rtruediv, + rxor, +) if TYPE_CHECKING: from pandas import ( From de8677b8f2270b6e54c4714acb24792b1c94e3b4 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 22 Mar 2021 14:00:58 +0100 Subject: [PATCH 3/4] move import in Block.where --- pandas/core/internals/blocks.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 800228156fcd6..f22392497c042 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -101,6 +101,7 @@ ) from pandas.core.base import PandasObject import pandas.core.common as com +import pandas.core.computation.expressions as expressions from pandas.core.construction import ( ensure_wrapped_if_datetimelike, extract_array, @@ -1303,8 +1304,6 @@ def where(self, other, cond, errors="raise", axis: int = 0) -> List[Block]: ------- List[Block] """ - import pandas.core.computation.expressions as expressions - assert not isinstance(other, (ABCIndex, ABCSeries, ABCDataFrame)) assert errors in ["raise", "ignore"] From 683eaeb587d1bf03831760fc947268aaee6d6592 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 22 Mar 2021 14:01:57 +0100 Subject: [PATCH 4/4] allow numexpr to be imported by default --- ci/code_checks.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index d74ef16765ef9..3b1774ade6f85 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -118,7 +118,7 @@ import sys import pandas blocklist = {'bs4', 'gcsfs', 'html5lib', 'http', 'ipython', 'jinja2', 'hypothesis', - 'lxml', 'matplotlib', 'numexpr', 'openpyxl', 'py', 'pytest', 's3fs', 'scipy', + 'lxml', 'matplotlib', 'openpyxl', 'py', 'pytest', 's3fs', 'scipy', 'tables', 'urllib.request', 'xlrd', 'xlsxwriter', 'xlwt'} # GH#28227 for some of these check for top-level modules, while others are