From 0e27d55c35baa1bd454d83ca5612767cd64efbb0 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Sat, 20 Apr 2019 10:38:00 -0400 Subject: [PATCH 1/3] TST: parameterize indexes base test to introspect ufuncs fails on numpy_dev --- pandas/tests/indexes/common.py | 57 ++----------------- pandas/tests/indexes/test_numpy_compat.py | 67 +++++++++++++++++++++++ 2 files changed, 71 insertions(+), 53 deletions(-) create mode 100644 pandas/tests/indexes/test_numpy_compat.py diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index b694d2c2dc44c..660eb244b3cfc 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -9,9 +9,9 @@ import pandas as pd from pandas import ( - CategoricalIndex, DatetimeIndex, Float64Index, Index, Int64Index, - IntervalIndex, MultiIndex, PeriodIndex, RangeIndex, Series, TimedeltaIndex, - UInt64Index, isna) + CategoricalIndex, DatetimeIndex, Index, Int64Index, IntervalIndex, + MultiIndex, PeriodIndex, RangeIndex, Series, TimedeltaIndex, UInt64Index, + isna) from pandas.core.indexes.base import InvalidIndexError from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin import pandas.util.testing as tm @@ -677,58 +677,9 @@ def test_equals_op(self): tm.assert_numpy_array_equal(index_a == item, expected3) tm.assert_series_equal(series_a == item, Series(expected3)) - def test_numpy_ufuncs(self): - # test ufuncs of numpy, see: - # http://docs.scipy.org/doc/numpy/reference/ufuncs.html - - for name, idx in self.indices.items(): - for func in [np.exp, np.exp2, np.expm1, np.log, np.log2, np.log10, - np.log1p, np.sqrt, np.sin, np.cos, np.tan, np.arcsin, - np.arccos, np.arctan, np.sinh, np.cosh, np.tanh, - np.arcsinh, np.arccosh, np.arctanh, np.deg2rad, - np.rad2deg]: - if isinstance(idx, DatetimeIndexOpsMixin): - # raise TypeError or ValueError (PeriodIndex) - # PeriodIndex behavior should be changed in future version - with pytest.raises(Exception): - with np.errstate(all='ignore'): - func(idx) - elif isinstance(idx, (Float64Index, Int64Index, UInt64Index)): - # coerces to float (e.g. np.sin) - with np.errstate(all='ignore'): - result = func(idx) - exp = Index(func(idx.values), name=idx.name) - - tm.assert_index_equal(result, exp) - assert isinstance(result, pd.Float64Index) - else: - # raise AttributeError or TypeError - if len(idx) == 0: - continue - else: - with pytest.raises(Exception): - with np.errstate(all='ignore'): - func(idx) - - for func in [np.isfinite, np.isinf, np.isnan, np.signbit]: - if isinstance(idx, DatetimeIndexOpsMixin): - # raise TypeError or ValueError (PeriodIndex) - with pytest.raises(Exception): - func(idx) - elif isinstance(idx, (Float64Index, Int64Index, UInt64Index)): - # Results in bool array - result = func(idx) - assert isinstance(result, np.ndarray) - assert not isinstance(result, Index) - else: - if len(idx) == 0: - continue - else: - with pytest.raises(Exception): - func(idx) - def test_hasnans_isnans(self): # GH 11343, added tests for hasnans / isnans + for name, index in self.indices.items(): if isinstance(index, MultiIndex): pass diff --git a/pandas/tests/indexes/test_numpy_compat.py b/pandas/tests/indexes/test_numpy_compat.py new file mode 100644 index 0000000000000..8e55577efc7e5 --- /dev/null +++ b/pandas/tests/indexes/test_numpy_compat.py @@ -0,0 +1,67 @@ +import numpy as np +import pytest + +from pandas import Float64Index, Index, Int64Index, UInt64Index +from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin +from pandas.util import testing as tm + + +@pytest.mark.parametrize( + 'func', [np.exp, np.exp2, np.expm1, np.log, np.log2, np.log10, + np.log1p, np.sqrt, np.sin, np.cos, np.tan, np.arcsin, + np.arccos, np.arctan, np.sinh, np.cosh, np.tanh, + np.arcsinh, np.arccosh, np.arctanh, np.deg2rad, + np.rad2deg], + ids=lambda x: x.__name__) +def test_numpy_ufuncs_basic(indices, func): + # test ufuncs of numpy, see: + # http://docs.scipy.org/doc/numpy/reference/ufuncs.html + + idx = indices + if isinstance(idx, DatetimeIndexOpsMixin): + # raise TypeError or ValueError (PeriodIndex) + # PeriodIndex behavior should be changed in future version + with pytest.raises(Exception): + with np.errstate(all='ignore'): + func(idx) + elif isinstance(idx, (Float64Index, Int64Index, UInt64Index)): + # coerces to float (e.g. np.sin) + with np.errstate(all='ignore'): + result = func(idx) + exp = Index(func(idx.values), name=idx.name) + + tm.assert_index_equal(result, exp) + assert isinstance(result, Float64Index) + else: + # raise AttributeError or TypeError + if len(idx) == 0: + pass + else: + with pytest.raises(Exception): + with np.errstate(all='ignore'): + func(idx) + + +@pytest.mark.parametrize( + 'func', [np.isfinite, np.isinf, np.isnan, np.signbit], + ids=lambda x: x.__name__) +def test_numpy_ufuncs_other(indices, func): + # test ufuncs of numpy, see: + # http://docs.scipy.org/doc/numpy/reference/ufuncs.html + + idx = indices + if isinstance(idx, DatetimeIndexOpsMixin): + # raise TypeError or ValueError (PeriodIndex) + with pytest.raises(Exception): + func(idx) + elif isinstance(idx, (Float64Index, Int64Index, UInt64Index)): + # Results in bool array + result = func(idx) + assert isinstance(result, np.ndarray) + assert not isinstance(result, Index) + else: + if len(idx) == 0: + pass + else: + with pytest.raises(Exception): + func(idx) From ceb0c83eb4946d4c8f4732115d7871e414ce20ec Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Sat, 20 Apr 2019 11:42:44 -0400 Subject: [PATCH 2/3] fix case for DTI/TDI --- pandas/tests/indexes/test_numpy_compat.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pandas/tests/indexes/test_numpy_compat.py b/pandas/tests/indexes/test_numpy_compat.py index 8e55577efc7e5..12f292ce3db37 100644 --- a/pandas/tests/indexes/test_numpy_compat.py +++ b/pandas/tests/indexes/test_numpy_compat.py @@ -1,7 +1,9 @@ import numpy as np import pytest -from pandas import Float64Index, Index, Int64Index, UInt64Index +from pandas import ( + DatetimeIndex, Float64Index, Index, Int64Index, TimedeltaIndex, + UInt64Index, _np_version_under1p17) from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin from pandas.util import testing as tm @@ -20,7 +22,6 @@ def test_numpy_ufuncs_basic(indices, func): idx = indices if isinstance(idx, DatetimeIndexOpsMixin): # raise TypeError or ValueError (PeriodIndex) - # PeriodIndex behavior should be changed in future version with pytest.raises(Exception): with np.errstate(all='ignore'): func(idx) @@ -50,10 +51,21 @@ def test_numpy_ufuncs_other(indices, func): # http://docs.scipy.org/doc/numpy/reference/ufuncs.html idx = indices - if isinstance(idx, DatetimeIndexOpsMixin): + if isinstance(idx, (DatetimeIndex, TimedeltaIndex)): + + # ok under numpy >= 1.17 + if not _np_version_under1p17 and func in [np.isfinite]: + pass + else: + # raise TypeError or ValueError (PeriodIndex) + with pytest.raises(Exception): + func(idx) + + elif isinstance(idx, DatetimeIndexOpsMixin): # raise TypeError or ValueError (PeriodIndex) with pytest.raises(Exception): func(idx) + elif isinstance(idx, (Float64Index, Int64Index, UInt64Index)): # Results in bool array result = func(idx) From e05fabf6b157e223df6950e845c50688265a09bb Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Sat, 20 Apr 2019 12:08:54 -0400 Subject: [PATCH 3/3] check output --- pandas/tests/indexes/test_numpy_compat.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/tests/indexes/test_numpy_compat.py b/pandas/tests/indexes/test_numpy_compat.py index 12f292ce3db37..460faaaf092ec 100644 --- a/pandas/tests/indexes/test_numpy_compat.py +++ b/pandas/tests/indexes/test_numpy_compat.py @@ -55,7 +55,10 @@ def test_numpy_ufuncs_other(indices, func): # ok under numpy >= 1.17 if not _np_version_under1p17 and func in [np.isfinite]: - pass + # Results in bool array + result = func(idx) + assert isinstance(result, np.ndarray) + assert not isinstance(result, Index) else: # raise TypeError or ValueError (PeriodIndex) with pytest.raises(Exception):