From 558cdbec47c9d9e7862a3d3c688fcf51260d367d Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 28 Jan 2019 20:58:04 -0600 Subject: [PATCH 01/11] REF: Move numpy tests down a directory --- pandas/tests/extension/numpy_/__init__.py | 0 pandas/tests/extension/{ => numpy_}/test_numpy.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 pandas/tests/extension/numpy_/__init__.py rename pandas/tests/extension/{ => numpy_}/test_numpy.py (100%) diff --git a/pandas/tests/extension/numpy_/__init__.py b/pandas/tests/extension/numpy_/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/pandas/tests/extension/test_numpy.py b/pandas/tests/extension/numpy_/test_numpy.py similarity index 100% rename from pandas/tests/extension/test_numpy.py rename to pandas/tests/extension/numpy_/test_numpy.py From 38e7413f3f650230eca75ab50580630838930c34 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 28 Jan 2019 20:59:58 -0600 Subject: [PATCH 02/11] The fix --- pandas/core/arrays/numpy_.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/numpy_.py b/pandas/core/arrays/numpy_.py index 47517782e2bbf..791ff44303e96 100644 --- a/pandas/core/arrays/numpy_.py +++ b/pandas/core/arrays/numpy_.py @@ -222,7 +222,7 @@ def __getitem__(self, item): item = item._ndarray result = self._ndarray[item] - if not lib.is_scalar(result): + if not lib.is_scalar(item): result = type(self)(result) return result From 9122bb6d5e7f0eb2296016f35e9d8eb7ef7293e1 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 28 Jan 2019 21:43:38 -0600 Subject: [PATCH 03/11] implement skips --- pandas/tests/extension/numpy_/conftest.py | 53 +++++++++++++++++++++ pandas/tests/extension/numpy_/test_numpy.py | 34 ++++++++++--- 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 pandas/tests/extension/numpy_/conftest.py diff --git a/pandas/tests/extension/numpy_/conftest.py b/pandas/tests/extension/numpy_/conftest.py new file mode 100644 index 0000000000000..6cad25d971bb2 --- /dev/null +++ b/pandas/tests/extension/numpy_/conftest.py @@ -0,0 +1,53 @@ +import pytest + +# A set of Base EA tests that are know to not work for +# the object-dtype PandasArray holding nested data. +skips = { + 'BaseCastingTests.test_astype_str', + 'BaseConstructorsTests.test_array_from_scalars', + # tuple isn't instance of np.object + 'BaseGetitemTests.test_getitem_scalar', + # Can't pass tuples to _from_sequence + 'BaseGetitemTests.test_take_series', + # np.array shape inference + 'BaseInterfaceTests.test_array_interface', + # Can't construct expected. + 'BaseMethodsTests.test_unique', + 'BaseMethodsTests.test_combine_add', + 'BaseMethodsTests.test_shift_fill_value', + 'BaseMethodsTests.test_where_series', + 'BaseMethodsTests.test_repeat', + # Can't hash ndarray[tuple] + 'BaseMethodsTests.test_hash_pandas_object_works', + # Can't construct expected. + 'BaseReshapingTests.test_merge', + 'BaseReshapingTests.test_merge_on_extension_array', + 'BaseReshapingTests.test_merge_on_extension_array_duplicates', + + # ndarray setting + 'BaseSetitemTests.test_setitem_scalar_series', + 'BaseSetitemTests.test_setitem_sequence', + 'BaseSetitemTests.test_setitem_sequence_mismatched_length_raises', + 'BaseSetitemTests.test_setitem_sequence_broadcasts', + 'BaseSetitemTests.test_setitem_sequence_broadcasts', + 'BaseSetitemTests.test_setitem_loc_scalar_mixed', + 'BaseSetitemTests.test_setitem_iloc_scalar_mixed', + 'BaseSetitemTests.test_setitem_loc_scalar_multiple_homogoneous', + 'BaseSetitemTests.test_setitem_iloc_scalar_multiple_homogoneous', + 'BaseSetitemTests.test_setitem_mask_broadcast', + 'BaseSetitemTests.test_setitem_scalar_key_sequence_raise', + + 'BaseParsingTests.test_EA_types', +} + + +def pytest_collection_modifyitems(config, items): + skip = pytest.mark.skip(reason="Skipping this because ...") + for item in items: + # TODO: See if pytest has a better way to resolve the *value* + # supplied to a fixture. Right now .keywords gets things + # like 'object' or 'data-object'. + parts = item.name.split("[") + if (len(parts) > 1 and 'object' in item.name.split('[')[1] + and item.obj.__qualname__ in skips): + item.add_marker(skip) diff --git a/pandas/tests/extension/numpy_/test_numpy.py b/pandas/tests/extension/numpy_/test_numpy.py index 7ca6882c7441b..f2c6b956b0bbd 100644 --- a/pandas/tests/extension/numpy_/test_numpy.py +++ b/pandas/tests/extension/numpy_/test_numpy.py @@ -6,12 +6,12 @@ from pandas.core.arrays.numpy_ import PandasArray, PandasDtype import pandas.util.testing as tm -from . import base +from .. import base -@pytest.fixture -def dtype(): - return PandasDtype(np.dtype('float')) +@pytest.fixture(params=['float', 'object']) +def dtype(request): + return PandasDtype(np.dtype(request.param)) @pytest.fixture @@ -38,6 +38,8 @@ def allow_in_pandas(monkeypatch): @pytest.fixture def data(allow_in_pandas, dtype): + if dtype.numpy_dtype == 'object': + return pd.Series([(i,) for i in range(100)]).array return PandasArray(np.arange(1, 101, dtype=dtype._dtype)) @@ -150,6 +152,19 @@ class TestArithmetics(BaseNumPyTests, base.BaseArithmeticOpsTests): frame_scalar_exc = None series_array_exc = None + def _check_op(self, s, op, other, op_name, exc=NotImplementedError): + if s.dtype == 'object': + raise pytest.skip("Skipping for object dtype.") + super(TestArithmetics, self)._check_op(s, op, other, op_name, exc) + + def _check_divmod_op(self, s, op, other, exc=Exception): + if isinstance(s, pd.Series) and s.dtype == 'object': + raise pytest.skip("Skipping for object dtype.") + elif isinstance(other, pd.Series) and other.dtype == 'object': + raise pytest.skip("Skipping for object dtype.") + + super(TestArithmetics, self)._check_divmod_op(s, op, other, exc) + def test_divmod_series_array(self, data): s = pd.Series(data) self._check_divmod_op(s, divmod, data, exc=None) @@ -186,6 +201,8 @@ class TestPrinting(BaseNumPyTests, base.BasePrintingTests): class TestNumericReduce(BaseNumPyTests, base.BaseNumericReduceTests): def check_reduce(self, s, op_name, skipna): + if s.dtype == 'object': + raise pytest.skip("Skipping for object dtype.") result = getattr(s, op_name)(skipna=skipna) # avoid coercing int -> float. Just cast to the actual numpy type. expected = getattr(s.astype(s.dtype._dtype), op_name)(skipna=skipna) @@ -193,10 +210,15 @@ def check_reduce(self, s, op_name, skipna): class TestBooleanReduce(BaseNumPyTests, base.BaseBooleanReduceTests): - pass + + def check_reduce(self, s, op_name, skipna): + if s.dtype == 'object': + raise pytest.skip("Skipping for object dtype.") + + super(TestBooleanReduce, self).check_reduce(s, op_name, skipna) -class TestMising(BaseNumPyTests, base.BaseMissingTests): +class TestMissing(BaseNumPyTests, base.BaseMissingTests): pass From 86948a1b52e67cbb432201ef499a685489320aa5 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 28 Jan 2019 21:50:07 -0600 Subject: [PATCH 04/11] fixed skip message --- pandas/tests/extension/numpy_/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/extension/numpy_/conftest.py b/pandas/tests/extension/numpy_/conftest.py index 6cad25d971bb2..661196333eefe 100644 --- a/pandas/tests/extension/numpy_/conftest.py +++ b/pandas/tests/extension/numpy_/conftest.py @@ -42,7 +42,7 @@ def pytest_collection_modifyitems(config, items): - skip = pytest.mark.skip(reason="Skipping this because ...") + skip = pytest.mark.skip(reason="Skipping for nested data.") for item in items: # TODO: See if pytest has a better way to resolve the *value* # supplied to a fixture. Right now .keywords gets things From 642b01a760622ad780a07d87e31376e26510610c Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Tue, 29 Jan 2019 07:19:41 -0600 Subject: [PATCH 05/11] py2 compat --- pandas/tests/extension/numpy_/conftest.py | 56 ++++++++++++----------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/pandas/tests/extension/numpy_/conftest.py b/pandas/tests/extension/numpy_/conftest.py index 661196333eefe..23a1774ddaaf2 100644 --- a/pandas/tests/extension/numpy_/conftest.py +++ b/pandas/tests/extension/numpy_/conftest.py @@ -3,41 +3,42 @@ # A set of Base EA tests that are know to not work for # the object-dtype PandasArray holding nested data. skips = { - 'BaseCastingTests.test_astype_str', - 'BaseConstructorsTests.test_array_from_scalars', + 'TestCasting.test_astype_str', + 'TestConstructors.test_array_from_scalars', # tuple isn't instance of np.object - 'BaseGetitemTests.test_getitem_scalar', + 'TestGetitem.test_getitem_scalar', # Can't pass tuples to _from_sequence - 'BaseGetitemTests.test_take_series', + 'TestGetitem.test_take_series', # np.array shape inference - 'BaseInterfaceTests.test_array_interface', + 'TestInterface.test_array_interface', # Can't construct expected. - 'BaseMethodsTests.test_unique', - 'BaseMethodsTests.test_combine_add', - 'BaseMethodsTests.test_shift_fill_value', - 'BaseMethodsTests.test_where_series', - 'BaseMethodsTests.test_repeat', + 'TestMethods.test_unique', + 'TestMethods.test_combine_add', + 'TestMethods.test_shift_fill_value', + 'TestMethods.test_where_series', + 'TestMethods.test_repeat', # Can't hash ndarray[tuple] - 'BaseMethodsTests.test_hash_pandas_object_works', + 'TestMethods.test_hash_pandas_object_works', # Can't construct expected. - 'BaseReshapingTests.test_merge', - 'BaseReshapingTests.test_merge_on_extension_array', - 'BaseReshapingTests.test_merge_on_extension_array_duplicates', + 'TestReshaping.test_merge', + 'TestReshaping.test_merge_on_extension_array', + 'TestReshaping.test_merge_on_extension_array_duplicates', # ndarray setting - 'BaseSetitemTests.test_setitem_scalar_series', - 'BaseSetitemTests.test_setitem_sequence', - 'BaseSetitemTests.test_setitem_sequence_mismatched_length_raises', - 'BaseSetitemTests.test_setitem_sequence_broadcasts', - 'BaseSetitemTests.test_setitem_sequence_broadcasts', - 'BaseSetitemTests.test_setitem_loc_scalar_mixed', - 'BaseSetitemTests.test_setitem_iloc_scalar_mixed', - 'BaseSetitemTests.test_setitem_loc_scalar_multiple_homogoneous', - 'BaseSetitemTests.test_setitem_iloc_scalar_multiple_homogoneous', - 'BaseSetitemTests.test_setitem_mask_broadcast', - 'BaseSetitemTests.test_setitem_scalar_key_sequence_raise', + 'TestSetitem.test_setitem_scalar_series', + 'TestSetitem.test_setitem_sequence', + 'TestSetitem.test_setitem_sequence_mismatched_length_raises', + 'TestSetitem.test_setitem_sequence_broadcasts', + 'TestSetitem.test_setitem_sequence_broadcasts', + 'TestSetitem.test_setitem_loc_scalar_mixed', + 'TestSetitem.test_setitem_iloc_scalar_mixed', + 'TestSetitem.test_setitem_loc_scalar_multiple_homogoneous', + 'TestSetitem.test_setitem_iloc_scalar_multiple_homogoneous', + 'TestSetitem.test_setitem_mask_broadcast', + 'TestSetitem.test_setitem_scalar_key_sequence_raise', - 'BaseParsingTests.test_EA_types', + # parsing differs. + 'TestParsing.test_EA_types', } @@ -48,6 +49,7 @@ def pytest_collection_modifyitems(config, items): # supplied to a fixture. Right now .keywords gets things # like 'object' or 'data-object'. parts = item.name.split("[") + qualname = item.parent.obj.__class__.__name__ + '.' + item.obj.__name__ if (len(parts) > 1 and 'object' in item.name.split('[')[1] - and item.obj.__qualname__ in skips): + and qualname in skips): item.add_marker(skip) From 518315cb0a9a133abb8c22c5019bf0b159760e82 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Tue, 29 Jan 2019 09:08:15 -0600 Subject: [PATCH 06/11] seperate file --- pandas/tests/extension/numpy_/conftest.py | 89 +++--- pandas/tests/extension/numpy_/test_numpy.py | 64 +--- .../extension/numpy_/test_numpy_nested.py | 285 ++++++++++++++++++ 3 files changed, 325 insertions(+), 113 deletions(-) create mode 100644 pandas/tests/extension/numpy_/test_numpy_nested.py diff --git a/pandas/tests/extension/numpy_/conftest.py b/pandas/tests/extension/numpy_/conftest.py index 23a1774ddaaf2..af1ebd05800ff 100644 --- a/pandas/tests/extension/numpy_/conftest.py +++ b/pandas/tests/extension/numpy_/conftest.py @@ -1,55 +1,38 @@ +import numpy as np import pytest -# A set of Base EA tests that are know to not work for -# the object-dtype PandasArray holding nested data. -skips = { - 'TestCasting.test_astype_str', - 'TestConstructors.test_array_from_scalars', - # tuple isn't instance of np.object - 'TestGetitem.test_getitem_scalar', - # Can't pass tuples to _from_sequence - 'TestGetitem.test_take_series', - # np.array shape inference - 'TestInterface.test_array_interface', - # Can't construct expected. - 'TestMethods.test_unique', - 'TestMethods.test_combine_add', - 'TestMethods.test_shift_fill_value', - 'TestMethods.test_where_series', - 'TestMethods.test_repeat', - # Can't hash ndarray[tuple] - 'TestMethods.test_hash_pandas_object_works', - # Can't construct expected. - 'TestReshaping.test_merge', - 'TestReshaping.test_merge_on_extension_array', - 'TestReshaping.test_merge_on_extension_array_duplicates', - - # ndarray setting - 'TestSetitem.test_setitem_scalar_series', - 'TestSetitem.test_setitem_sequence', - 'TestSetitem.test_setitem_sequence_mismatched_length_raises', - 'TestSetitem.test_setitem_sequence_broadcasts', - 'TestSetitem.test_setitem_sequence_broadcasts', - 'TestSetitem.test_setitem_loc_scalar_mixed', - 'TestSetitem.test_setitem_iloc_scalar_mixed', - 'TestSetitem.test_setitem_loc_scalar_multiple_homogoneous', - 'TestSetitem.test_setitem_iloc_scalar_multiple_homogoneous', - 'TestSetitem.test_setitem_mask_broadcast', - 'TestSetitem.test_setitem_scalar_key_sequence_raise', - - # parsing differs. - 'TestParsing.test_EA_types', -} - - -def pytest_collection_modifyitems(config, items): - skip = pytest.mark.skip(reason="Skipping for nested data.") - for item in items: - # TODO: See if pytest has a better way to resolve the *value* - # supplied to a fixture. Right now .keywords gets things - # like 'object' or 'data-object'. - parts = item.name.split("[") - qualname = item.parent.obj.__class__.__name__ + '.' + item.obj.__name__ - if (len(parts) > 1 and 'object' in item.name.split('[')[1] - and qualname in skips): - item.add_marker(skip) +from pandas.core.arrays.numpy_ import PandasArray + + +@pytest.fixture +def allow_in_pandas(monkeypatch): + """ + A monkeypatch to tells pandas to let us in. + + By default, passing a PandasArray to an index / series / frame + constructor will unbox that PandasArray to an ndarray, and treat + it as a non-EA column. We don't want people using EAs without + reason. + + The mechanism for this is a check against ABCPandasArray + in each constructor. + + But, for testing, we need to allow them in pandas. So we patch + the _typ of PandasArray, so that we evade the ABCPandasArray + check. + """ + with monkeypatch.context() as m: + m.setattr(PandasArray, '_typ', 'extension') + yield + + +@pytest.fixture +def na_value(): + return np.nan + + +@pytest.fixture +def na_cmp(): + def cmp(a, b): + return np.isnan(a) and np.isnan(b) + return cmp diff --git a/pandas/tests/extension/numpy_/test_numpy.py b/pandas/tests/extension/numpy_/test_numpy.py index f2c6b956b0bbd..4c93d5ee0b9d7 100644 --- a/pandas/tests/extension/numpy_/test_numpy.py +++ b/pandas/tests/extension/numpy_/test_numpy.py @@ -9,37 +9,13 @@ from .. import base -@pytest.fixture(params=['float', 'object']) -def dtype(request): - return PandasDtype(np.dtype(request.param)) - - @pytest.fixture -def allow_in_pandas(monkeypatch): - """ - A monkeypatch to tells pandas to let us in. - - By default, passing a PandasArray to an index / series / frame - constructor will unbox that PandasArray to an ndarray, and treat - it as a non-EA column. We don't want people using EAs without - reason. - - The mechanism for this is a check against ABCPandasArray - in each constructor. - - But, for testing, we need to allow them in pandas. So we patch - the _typ of PandasArray, so that we evade the ABCPandasArray - check. - """ - with monkeypatch.context() as m: - m.setattr(PandasArray, '_typ', 'extension') - yield +def dtype(): + return PandasDtype(np.dtype('float')) @pytest.fixture def data(allow_in_pandas, dtype): - if dtype.numpy_dtype == 'object': - return pd.Series([(i,) for i in range(100)]).array return PandasArray(np.arange(1, 101, dtype=dtype._dtype)) @@ -48,18 +24,6 @@ def data_missing(allow_in_pandas): return PandasArray(np.array([np.nan, 1.0])) -@pytest.fixture -def na_value(): - return np.nan - - -@pytest.fixture -def na_cmp(): - def cmp(a, b): - return np.isnan(a) and np.isnan(b) - return cmp - - @pytest.fixture def data_for_sorting(allow_in_pandas): """Length-3 array with a known sort order. @@ -152,19 +116,6 @@ class TestArithmetics(BaseNumPyTests, base.BaseArithmeticOpsTests): frame_scalar_exc = None series_array_exc = None - def _check_op(self, s, op, other, op_name, exc=NotImplementedError): - if s.dtype == 'object': - raise pytest.skip("Skipping for object dtype.") - super(TestArithmetics, self)._check_op(s, op, other, op_name, exc) - - def _check_divmod_op(self, s, op, other, exc=Exception): - if isinstance(s, pd.Series) and s.dtype == 'object': - raise pytest.skip("Skipping for object dtype.") - elif isinstance(other, pd.Series) and other.dtype == 'object': - raise pytest.skip("Skipping for object dtype.") - - super(TestArithmetics, self)._check_divmod_op(s, op, other, exc) - def test_divmod_series_array(self, data): s = pd.Series(data) self._check_divmod_op(s, divmod, data, exc=None) @@ -201,8 +152,6 @@ class TestPrinting(BaseNumPyTests, base.BasePrintingTests): class TestNumericReduce(BaseNumPyTests, base.BaseNumericReduceTests): def check_reduce(self, s, op_name, skipna): - if s.dtype == 'object': - raise pytest.skip("Skipping for object dtype.") result = getattr(s, op_name)(skipna=skipna) # avoid coercing int -> float. Just cast to the actual numpy type. expected = getattr(s.astype(s.dtype._dtype), op_name)(skipna=skipna) @@ -210,15 +159,10 @@ def check_reduce(self, s, op_name, skipna): class TestBooleanReduce(BaseNumPyTests, base.BaseBooleanReduceTests): - - def check_reduce(self, s, op_name, skipna): - if s.dtype == 'object': - raise pytest.skip("Skipping for object dtype.") - - super(TestBooleanReduce, self).check_reduce(s, op_name, skipna) + pass -class TestMissing(BaseNumPyTests, base.BaseMissingTests): +class TestMising(BaseNumPyTests, base.BaseMissingTests): pass diff --git a/pandas/tests/extension/numpy_/test_numpy_nested.py b/pandas/tests/extension/numpy_/test_numpy_nested.py new file mode 100644 index 0000000000000..186431638f7fd --- /dev/null +++ b/pandas/tests/extension/numpy_/test_numpy_nested.py @@ -0,0 +1,285 @@ +import numpy as np +import pytest + +import pandas as pd +from pandas.core.arrays.numpy_ import PandasArray, PandasDtype + +from .. import base + + +@pytest.fixture +def dtype(): + return PandasDtype(np.dtype('object')) + + +@pytest.fixture +def data(allow_in_pandas, dtype): + return pd.Series([(i,) for i in range(100)]).array + + +@pytest.fixture +def data_missing(allow_in_pandas): + return PandasArray(np.array([np.nan, (1,)])) + + +@pytest.fixture +def na_value(): + return np.nan + + +@pytest.fixture +def na_cmp(): + def cmp(a, b): + return np.isnan(a) and np.isnan(b) + return cmp + + +@pytest.fixture +def data_for_sorting(allow_in_pandas): + """Length-3 array with a known sort order. + + This should be three items [B, C, A] with + A < B < C + """ + # Use an empty tuple for first element, then remove, + # to disable np.array's shape inference. + return PandasArray( + np.array([(), (2,), (3,), (1,)])[1:] + ) + + +@pytest.fixture +def data_missing_for_sorting(allow_in_pandas): + """Length-3 array with a known sort order. + + This should be three items [B, NA, A] with + A < B and NA missing. + """ + return PandasArray( + np.array([(1,), np.nan, (0,)]) + ) + + +@pytest.fixture +def data_for_grouping(allow_in_pandas): + """Data for factorization, grouping, and unique tests. + + Expected to be like [B, B, NA, NA, A, A, B, C] + + Where A < B < C and NA is missing + """ + a, b, c = (1,), (2,), (3,) + return PandasArray(np.array( + [b, b, np.nan, np.nan, a, a, b, c] + )) + + +skip_nested = pytest.mark.skip(reason="Skipping for nested PandasArray") + + +class BaseNumPyTests(object): + pass + + +class TestCasting(BaseNumPyTests, base.BaseCastingTests): + + @skip_nested + def test_astype_str(self, data): + pass + + +class TestConstructors(BaseNumPyTests, base.BaseConstructorsTests): + @pytest.mark.skip(reason="We don't register our dtype") + # We don't want to register. This test should probably be split in two. + def test_from_dtype(self, data): + pass + + @skip_nested + def test_array_from_scalars(self, data): + pass + + +class TestDtype(BaseNumPyTests, base.BaseDtypeTests): + + @pytest.mark.skip(reason="Incorrect expected.") + # we unsurprisingly clash with a NumPy name. + def test_check_dtype(self, data): + pass + + +class TestGetitem(BaseNumPyTests, base.BaseGetitemTests): + + @skip_nested + def test_getitem_scalar(self, data): + pass + + @skip_nested + def test_take_series(self, data): + pass + + +class TestGroupby(BaseNumPyTests, base.BaseGroupbyTests): + @skip_nested + def test_groupby_extension_apply(self, data_for_grouping, op): + pass + + +class TestInterface(BaseNumPyTests, base.BaseInterfaceTests): + @skip_nested + def test_array_interface(self, data): + # NumPy array shape inference + pass + + +class TestMethods(BaseNumPyTests, base.BaseMethodsTests): + + @pytest.mark.skip(reason="TODO: remove?") + def test_value_counts(self, all_data, dropna): + pass + + @pytest.mark.skip(reason="Incorrect expected") + # We have a bool dtype, so the result is an ExtensionArray + # but expected is not + def test_combine_le(self, data_repeated): + super(TestMethods, self).test_combine_le(data_repeated) + + @skip_nested + def test_combine_add(self, data_repeated): + # Not numeric + pass + + @skip_nested + def test_shift_fill_value(self, data): + # np.array shape inference. Shift implementation fails. + super().test_shift_fill_value(data) + + @skip_nested + def test_unique(self, data, box, method): + # Fails creating expected + pass + + @skip_nested + def test_fillna_copy_frame(self, data_missing): + # The "scalar" for this array isn't a scalar. + pass + + @skip_nested + def test_fillna_copy_series(self, data_missing): + # The "scalar" for this array isn't a scalar. + pass + + @skip_nested + def test_hash_pandas_object_works(self, data, as_frame): + # ndarray of tuples not hashable + pass + + @skip_nested + def test_searchsorted(self, data_for_sorting, as_series): + # Test setup fails. + pass + + @skip_nested + def test_where_series(self, data, na_value, as_frame): + # Test setup fails. + pass + + @skip_nested + def test_repeat(self, data, repeats, as_series, use_numpy): + # Fails creating expected + pass + + +class TestPrinting(BaseNumPyTests, base.BasePrintingTests): + pass + + +class TestMissing(BaseNumPyTests, base.BaseMissingTests): + + @skip_nested + def test_fillna_scalar(self, data_missing): + # Non-scalar "scalar" values. + pass + + @skip_nested + def test_fillna_series_method(self, data_missing, method): + # Non-scalar "scalar" values. + pass + + @skip_nested + def test_fillna_series(self, data_missing): + # Non-scalar "scalar" values. + pass + + @skip_nested + def test_fillna_frame(self, data_missing): + # Non-scalar "scalar" values. + pass + + +class TestReshaping(BaseNumPyTests, base.BaseReshapingTests): + + @pytest.mark.skip("Incorrect parent test") + # not actually a mixed concat, since we concat int and int. + def test_concat_mixed_dtypes(self, data): + super(TestReshaping, self).test_concat_mixed_dtypes(data) + + @skip_nested + def test_merge(self, data, na_value): + # Fails creating expected + pass + + @skip_nested + def test_merge_on_extension_array(self, data): + # Fails creating expected + pass + + @skip_nested + def test_merge_on_extension_array_duplicates(self, data): + # Fails creating expected + pass + + +class TestSetitem(BaseNumPyTests, base.BaseSetitemTests): + + @skip_nested + def test_setitem_scalar_series(self, data, box_in_series): + pass + + @skip_nested + def test_setitem_sequence(self, data, box_in_series): + pass + + @skip_nested + def test_setitem_sequence_mismatched_length_raises(self, data, as_array): + pass + + @skip_nested + def test_setitem_sequence_broadcasts(self, data, box_in_series): + pass + + @skip_nested + def test_setitem_loc_scalar_mixed(self, data): + pass + + @skip_nested + def test_setitem_loc_scalar_multiple_homogoneous(self, data): + pass + + @skip_nested + def test_setitem_iloc_scalar_mixed(self, data): + pass + + @skip_nested + def test_setitem_iloc_scalar_multiple_homogoneous(self, data): + pass + + @skip_nested + def test_setitem_mask_broadcast(self, data, setter): + pass + + @skip_nested + def test_setitem_scalar_key_sequence_raise(self, data): + pass + + +# Skip Arithmetics, NumericReduce, BooleanReduce, Parsing From 6d7e0d80eb71cc5e7497182f00f996d6eae4a259 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Tue, 29 Jan 2019 09:11:56 -0600 Subject: [PATCH 07/11] remove duplicate fixtures --- pandas/tests/extension/numpy_/test_numpy_nested.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pandas/tests/extension/numpy_/test_numpy_nested.py b/pandas/tests/extension/numpy_/test_numpy_nested.py index 186431638f7fd..0c4e3b2163ca3 100644 --- a/pandas/tests/extension/numpy_/test_numpy_nested.py +++ b/pandas/tests/extension/numpy_/test_numpy_nested.py @@ -22,18 +22,6 @@ def data_missing(allow_in_pandas): return PandasArray(np.array([np.nan, (1,)])) -@pytest.fixture -def na_value(): - return np.nan - - -@pytest.fixture -def na_cmp(): - def cmp(a, b): - return np.isnan(a) and np.isnan(b) - return cmp - - @pytest.fixture def data_for_sorting(allow_in_pandas): """Length-3 array with a known sort order. From bf1efc93dbf74c1c66687939bfc70a550254a30f Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Tue, 29 Jan 2019 10:22:26 -0600 Subject: [PATCH 08/11] Skip for old NumPy --- pandas/tests/extension/numpy_/test_numpy_nested.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/tests/extension/numpy_/test_numpy_nested.py b/pandas/tests/extension/numpy_/test_numpy_nested.py index 0c4e3b2163ca3..31eec3d4249c4 100644 --- a/pandas/tests/extension/numpy_/test_numpy_nested.py +++ b/pandas/tests/extension/numpy_/test_numpy_nested.py @@ -1,4 +1,3 @@ -import numpy as np import pytest import pandas as pd @@ -6,6 +5,10 @@ from .. import base +# For NumPy <1.16, np.array([np.nan, (1,)]) raises +# ValueError: setting an array element with a sequence. +np = pytest.importorskip('numpy', minversion='1.16.0') + @pytest.fixture def dtype(): From cc246c9f2be36f18592235a825ac4608ab7e13ec Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 30 Jan 2019 08:02:56 -0600 Subject: [PATCH 09/11] comment --- pandas/tests/extension/numpy_/test_numpy_nested.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/tests/extension/numpy_/test_numpy_nested.py b/pandas/tests/extension/numpy_/test_numpy_nested.py index 31eec3d4249c4..58001e782be7e 100644 --- a/pandas/tests/extension/numpy_/test_numpy_nested.py +++ b/pandas/tests/extension/numpy_/test_numpy_nested.py @@ -1,3 +1,8 @@ +""" +Tests for PandasArray with nested data. Users typically won't create +these objects via `pd.array`, but they can show up through `.array` +on a Series with nested data. +""" import pytest import pandas as pd From 7cf5583957676f0843276e6246efaa7014513d36 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Wed, 30 Jan 2019 08:42:51 -0600 Subject: [PATCH 10/11] Update pandas/tests/extension/numpy_/conftest.py Co-Authored-By: TomAugspurger --- pandas/tests/extension/numpy_/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/extension/numpy_/conftest.py b/pandas/tests/extension/numpy_/conftest.py index af1ebd05800ff..daa93571c2957 100644 --- a/pandas/tests/extension/numpy_/conftest.py +++ b/pandas/tests/extension/numpy_/conftest.py @@ -7,7 +7,7 @@ @pytest.fixture def allow_in_pandas(monkeypatch): """ - A monkeypatch to tells pandas to let us in. + A monkeypatch to tell pandas to let us in. By default, passing a PandasArray to an index / series / frame constructor will unbox that PandasArray to an ndarray, and treat From 358df869e6a70973a117bb5f5e5d53492945012e Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 30 Jan 2019 10:31:44 -0600 Subject: [PATCH 11/11] Update test_numpy_nested.py [ci skip] --- pandas/tests/extension/numpy_/test_numpy_nested.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/tests/extension/numpy_/test_numpy_nested.py b/pandas/tests/extension/numpy_/test_numpy_nested.py index 58001e782be7e..cf9b34dd08798 100644 --- a/pandas/tests/extension/numpy_/test_numpy_nested.py +++ b/pandas/tests/extension/numpy_/test_numpy_nested.py @@ -2,6 +2,11 @@ Tests for PandasArray with nested data. Users typically won't create these objects via `pd.array`, but they can show up through `.array` on a Series with nested data. + +We partition these tests into their own file, as many of the base +tests fail, as they aren't appropriate for nested data. It is easier +to have a seperate file with its own data generating fixtures, than +trying to skip based upon the value of a fixture. """ import pytest