From 2cea646c0c5ba76b3d61ac5bec3a8e9922ed81f0 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 08:32:10 -0500 Subject: [PATCH 1/8] BUG: Avoid exceptions in is_dtype --- pandas/core/dtypes/base.py | 8 +++++++- pandas/tests/dtypes/test_dtypes.py | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/pandas/core/dtypes/base.py b/pandas/core/dtypes/base.py index a552251ebbafa..db0a917aefb85 100644 --- a/pandas/core/dtypes/base.py +++ b/pandas/core/dtypes/base.py @@ -2,6 +2,7 @@ import numpy as np from pandas import compat +from pandas.core.dtypes.generic import ABCSeries, ABCIndexClass, ABCDataFrame from pandas.errors import AbstractMethodError @@ -83,7 +84,12 @@ def is_dtype(cls, dtype): """ dtype = getattr(dtype, 'dtype', dtype) - if isinstance(dtype, np.dtype): + if isinstance(dtype, (ABCSeries, ABCIndexClass, + ABCDataFrame, np.dtype)): + # https://github.com/pandas-dev/pandas/issues/22960 + # avoid passing data to `construct_from_string`. This could + # cause a FutureWarning from numpy about failing elementwise + # comparison from, e.g., comparing DataFrame == 'category'. return False elif dtype is None: return False diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py index e3d14497a38f9..7e95b076a8a66 100644 --- a/pandas/tests/dtypes/test_dtypes.py +++ b/pandas/tests/dtypes/test_dtypes.py @@ -815,3 +815,23 @@ def test_registry_find(dtype, expected): ('datetime64[ns, US/Eastern]', DatetimeTZDtype('ns', 'US/Eastern'))]) def test_pandas_registry_find(dtype, expected): assert _pandas_registry.find(dtype) == expected + + +@pytest.mark.parametrize("check", [ + is_categorical_dtype, + is_datetime64tz_dtype, + is_period_dtype, + is_datetime64_ns_dtype, + is_datetime64_dtype, + is_interval_dtype, + is_datetime64_any_dtype, + is_string_dtype, + is_bool_dtype, +]) +def test_is_dtype_no_warning(check): + data = pd.DataFrame({"A": [1, 2]}) + with tm.assert_produces_warning(None): + check(data) + + with tm.assert_produces_warning(None): + check(data["A"]) From 88fd6c2bd4a61a346bf35aaad2066177cd64f3b2 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 08:40:59 -0500 Subject: [PATCH 2/8] move --- .travis.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40baee2c03ea0..c9bdb91283d42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,11 +53,7 @@ matrix: - dist: trusty env: - JOB="3.6, coverage" ENV_FILE="ci/travis-36.yaml" TEST_ARGS="--skip-slow --skip-network" PANDAS_TESTING_MODE="deprecate" COVERAGE=true DOCTEST=true - # In allow_failures - - dist: trusty - env: - - JOB="3.6, slow" ENV_FILE="ci/travis-36-slow.yaml" SLOW=true - # In allow_failures + - dist: trusty env: - JOB="3.7, NumPy dev" ENV_FILE="ci/travis-37-numpydev.yaml" TEST_ARGS="--skip-slow --skip-network -W error" PANDAS_TESTING_MODE="deprecate" @@ -65,6 +61,12 @@ matrix: apt: packages: - xsel + + # In allow_failures + - dist: trusty + env: + - JOB="3.6, slow" ENV_FILE="ci/travis-36-slow.yaml" SLOW=true + # In allow_failures - dist: trusty env: @@ -73,13 +75,6 @@ matrix: - dist: trusty env: - JOB="3.6, slow" ENV_FILE="ci/travis-36-slow.yaml" SLOW=true - - dist: trusty - env: - - JOB="3.7, NumPy dev" ENV_FILE="ci/travis-37-numpydev.yaml" TEST_ARGS="--skip-slow --skip-network -W error" PANDAS_TESTING_MODE="deprecate" - addons: - apt: - packages: - - xsel - dist: trusty env: - JOB="3.6, doc" ENV_FILE="ci/travis-36-doc.yaml" DOC=true From b17113edab786ad67b3cc715fb4e39ea679855f4 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 09:42:29 -0500 Subject: [PATCH 3/8] Catch numpy warning --- pandas/core/frame.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ff7590f6d5358..f4b7ccb0fdf5b 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4908,7 +4908,8 @@ def _combine_match_index(self, other, func, level=None): return ops.dispatch_to_series(left, right, func) else: # fastpath --> operate directly on values - new_data = func(left.values.T, right.values).T + with np.errstate(all="ignore"): + new_data = func(left.values.T, right.values).T return self._constructor(new_data, index=left.index, columns=self.columns, copy=False) From 797c790645762159ee5b2b08498607ced6c052a0 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 11:35:06 -0500 Subject: [PATCH 4/8] Avoid (maybe) unnecessary cast to float dtype --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 82198c2b3edd5..fde83237b23d7 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -4224,7 +4224,7 @@ def _try_cast(arr, take_fast_path): try: # gh-15832: Check if we are requesting a numeric dype and # that we can convert the data to the requested dtype. - if is_float_dtype(dtype) or is_integer_dtype(dtype): + if is_integer_dtype(dtype): subarr = maybe_cast_to_integer_array(arr, dtype) subarr = maybe_cast_to_datetime(arr, dtype) From d88929f38c061d0e4506ba5bc00ab8002a7acb5e Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 12:59:20 -0500 Subject: [PATCH 5/8] Take 2 --- pandas/core/frame.py | 3 +-- pandas/core/ops.py | 15 ++++++++++++--- pandas/tests/frame/test_operators.py | 6 ++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index f4b7ccb0fdf5b..ff7590f6d5358 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4908,8 +4908,7 @@ def _combine_match_index(self, other, func, level=None): return ops.dispatch_to_series(left, right, func) else: # fastpath --> operate directly on values - with np.errstate(all="ignore"): - new_data = func(left.values.T, right.values).T + new_data = func(left.values.T, right.values).T return self._constructor(new_data, index=left.index, columns=self.columns, copy=False) diff --git a/pandas/core/ops.py b/pandas/core/ops.py index dc99faaf68f51..01ef7c850b835 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -138,6 +138,15 @@ def maybe_upcast_for_op(obj): return obj +def silent_truediv(x, y): + """Like operator.truediv, but with NumPy warnings silenced.""" + with np.errstate(all="ignore"): + return operator.truediv(x ,y) + + +silent_truediv.__name__ = 'truediv' +silent_truediv.__doc__ = operator.truediv.__doc__ + # ----------------------------------------------------------------------------- # Reversed Operations not available in the stdlib operator module. # Defining these instead of using lambdas allows us to reference them by name. @@ -159,7 +168,7 @@ def rdiv(left, right): def rtruediv(left, right): - return right / left + return silent_truediv(right, left) def rfloordiv(left, right): @@ -339,7 +348,7 @@ def _get_opstr(op, cls): rmul: '*', operator.sub: '-', rsub: '-', - operator.truediv: '/', + silent_truediv: '/', rtruediv: '/', operator.floordiv: '//', rfloordiv: '//', @@ -1012,7 +1021,7 @@ def _create_methods(cls, arith_method, comp_method, bool_method, special): radd=arith_method(cls, radd, special), sub=arith_method(cls, operator.sub, special), mul=arith_method(cls, operator.mul, special), - truediv=arith_method(cls, operator.truediv, special), + truediv=arith_method(cls, silent_truediv, special), floordiv=arith_method(cls, operator.floordiv, special), # Causes a floating point exception in the tests when numexpr enabled, # so for now no speedup diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index 97c94e1134cc8..c768cde9b88bd 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -1030,3 +1030,9 @@ def test_alignment_non_pandas(self): align(df, val, 'index') with pytest.raises(ValueError): align(df, val, 'columns') + + def test_no_warning(self, all_arithmetic_operators): + df = pd.DataFrame({"A": [0.,0.], "B": [0., None]}) + b = df['B'] + with tm.assert_produces_warning(None): + getattr(df, all_arithmetic_operators)(b, 0) From f6cc86028b18b16867ef545b07bdc8c19437daec Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 13:58:43 -0500 Subject: [PATCH 6/8] Revert "Take 2" This reverts commit d88929f38c061d0e4506ba5bc00ab8002a7acb5e. --- pandas/core/frame.py | 3 ++- pandas/core/ops.py | 15 +++------------ pandas/tests/frame/test_operators.py | 6 ------ 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ff7590f6d5358..f4b7ccb0fdf5b 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4908,7 +4908,8 @@ def _combine_match_index(self, other, func, level=None): return ops.dispatch_to_series(left, right, func) else: # fastpath --> operate directly on values - new_data = func(left.values.T, right.values).T + with np.errstate(all="ignore"): + new_data = func(left.values.T, right.values).T return self._constructor(new_data, index=left.index, columns=self.columns, copy=False) diff --git a/pandas/core/ops.py b/pandas/core/ops.py index 01ef7c850b835..dc99faaf68f51 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -138,15 +138,6 @@ def maybe_upcast_for_op(obj): return obj -def silent_truediv(x, y): - """Like operator.truediv, but with NumPy warnings silenced.""" - with np.errstate(all="ignore"): - return operator.truediv(x ,y) - - -silent_truediv.__name__ = 'truediv' -silent_truediv.__doc__ = operator.truediv.__doc__ - # ----------------------------------------------------------------------------- # Reversed Operations not available in the stdlib operator module. # Defining these instead of using lambdas allows us to reference them by name. @@ -168,7 +159,7 @@ def rdiv(left, right): def rtruediv(left, right): - return silent_truediv(right, left) + return right / left def rfloordiv(left, right): @@ -348,7 +339,7 @@ def _get_opstr(op, cls): rmul: '*', operator.sub: '-', rsub: '-', - silent_truediv: '/', + operator.truediv: '/', rtruediv: '/', operator.floordiv: '//', rfloordiv: '//', @@ -1021,7 +1012,7 @@ def _create_methods(cls, arith_method, comp_method, bool_method, special): radd=arith_method(cls, radd, special), sub=arith_method(cls, operator.sub, special), mul=arith_method(cls, operator.mul, special), - truediv=arith_method(cls, silent_truediv, special), + truediv=arith_method(cls, operator.truediv, special), floordiv=arith_method(cls, operator.floordiv, special), # Causes a floating point exception in the tests when numexpr enabled, # so for now no speedup diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index c768cde9b88bd..97c94e1134cc8 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -1030,9 +1030,3 @@ def test_alignment_non_pandas(self): align(df, val, 'index') with pytest.raises(ValueError): align(df, val, 'columns') - - def test_no_warning(self, all_arithmetic_operators): - df = pd.DataFrame({"A": [0.,0.], "B": [0., None]}) - b = df['B'] - with tm.assert_produces_warning(None): - getattr(df, all_arithmetic_operators)(b, 0) From af8fca2bbf26c48476624fac05e5b164c3663444 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 14:00:40 -0500 Subject: [PATCH 7/8] Hmm, try the other approach --- pandas/tests/frame/test_operators.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index 97c94e1134cc8..70bf5afb92974 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -1030,3 +1030,9 @@ def test_alignment_non_pandas(self): align(df, val, 'index') with pytest.raises(ValueError): align(df, val, 'columns') + + def test_no_warning(self, all_arithmetic_operators): + df = pd.DataFrame({"A": [0.,0.], "B": [0., None]}) + b = df['B'] + with tm.assert_produces_warning(None): + getattr(df, all_arithmetic_operators)(b, 0) From 073df470ef2e645dd886d568490da50e4574acb4 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 3 Oct 2018 15:19:48 -0500 Subject: [PATCH 8/8] lint --- pandas/tests/frame/test_operators.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index 70bf5afb92974..6ed289614b96a 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -1032,7 +1032,7 @@ def test_alignment_non_pandas(self): align(df, val, 'columns') def test_no_warning(self, all_arithmetic_operators): - df = pd.DataFrame({"A": [0.,0.], "B": [0., None]}) - b = df['B'] - with tm.assert_produces_warning(None): - getattr(df, all_arithmetic_operators)(b, 0) + df = pd.DataFrame({"A": [0., 0.], "B": [0., None]}) + b = df['B'] + with tm.assert_produces_warning(None): + getattr(df, all_arithmetic_operators)(b, 0)