From 18dc4e3e3a250db6004f80877feb3230b4a8d44f Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Mon, 14 Mar 2022 21:56:06 -0700 Subject: [PATCH 1/4] TST: Fix warnings & skip -> xfail --- pandas/tests/arrays/string_/test_string.py | 2 +- pandas/tests/extension/base/ops.py | 2 +- pandas/tests/extension/json/test_json.py | 4 ++-- pandas/tests/extension/test_categorical.py | 9 +++----- pandas/tests/extension/test_datetime.py | 4 +--- pandas/tests/extension/test_interval.py | 24 ++++++++++++---------- pandas/tests/extension/test_numpy.py | 10 ++------- pandas/tests/extension/test_string.py | 10 +++------ pandas/tests/plotting/frame/test_frame.py | 7 +++---- pandas/tests/plotting/test_converter.py | 2 +- pyproject.toml | 1 + 11 files changed, 31 insertions(+), 44 deletions(-) diff --git a/pandas/tests/arrays/string_/test_string.py b/pandas/tests/arrays/string_/test_string.py index 8b2aea5c2e2e1..59b9d2f2f8908 100644 --- a/pandas/tests/arrays/string_/test_string.py +++ b/pandas/tests/arrays/string_/test_string.py @@ -523,7 +523,7 @@ def test_memory_usage(dtype): # GH 33963 if dtype.storage == "pyarrow": - pytest.skip("not applicable") + pytest.skip(f"not applicable for {dtype.storage}") series = pd.Series(["a", "b", "c"], dtype=dtype) diff --git a/pandas/tests/extension/base/ops.py b/pandas/tests/extension/base/ops.py index 1d3d736ca7ee2..bdb63a094e5c0 100644 --- a/pandas/tests/extension/base/ops.py +++ b/pandas/tests/extension/base/ops.py @@ -124,7 +124,7 @@ def test_direct_arith_with_ndframe_returns_not_implemented(self, data, box): result = data.__add__(other) assert result is NotImplemented else: - raise pytest.skip(f"{type(data).__name__} does not implement add") + pytest.skip(f"{type(data).__name__} does not implement add") class BaseComparisonOpsTests(BaseOpsUtil): diff --git a/pandas/tests/extension/json/test_json.py b/pandas/tests/extension/json/test_json.py index d530a75b74c8f..7dee81b62d2e8 100644 --- a/pandas/tests/extension/json/test_json.py +++ b/pandas/tests/extension/json/test_json.py @@ -155,10 +155,10 @@ def test_contains(self, data): class TestConstructors(BaseJSON, base.BaseConstructorsTests): - @pytest.mark.skip(reason="not implemented constructor from dtype") + @pytest.mark.xfail(reason="not implemented constructor from dtype") def test_from_dtype(self, data): # construct from our dtype & string dtype - pass + super(self).test_from_dtype(data) @pytest.mark.xfail(reason="RecursionError, GH-33900") def test_series_constructor_no_data_with_index(self, dtype, na_value): diff --git a/pandas/tests/extension/test_categorical.py b/pandas/tests/extension/test_categorical.py index d21110e078709..5dbccd6bf93b3 100644 --- a/pandas/tests/extension/test_categorical.py +++ b/pandas/tests/extension/test_categorical.py @@ -50,7 +50,7 @@ def data(): """Length-100 array for this type. * data[0] and data[1] should both be non missing - * data[0] and data[1] should not gbe equal + * data[0] and data[1] should not be equal """ return Categorical(make_data()) @@ -86,7 +86,7 @@ class TestDtype(base.BaseDtypeTests): class TestInterface(base.BaseInterfaceTests): - @pytest.mark.skip(reason="Memory usage doesn't match") + @pytest.mark.xfail(reason="Memory usage doesn't match") def test_memory_usage(self, data): # Is this deliberate? super().test_memory_usage(data) @@ -149,11 +149,9 @@ class TestIndex(base.BaseIndexTests): class TestMissing(base.BaseMissingTests): - @pytest.mark.skip(reason="Not implemented") def test_fillna_limit_pad(self, data_missing): super().test_fillna_limit_pad(data_missing) - @pytest.mark.skip(reason="Not implemented") def test_fillna_limit_backfill(self, data_missing): super().test_fillna_limit_backfill(data_missing) @@ -163,7 +161,7 @@ class TestReduce(base.BaseNoReduceTests): class TestMethods(base.BaseMethodsTests): - @pytest.mark.skip(reason="Unobserved categories included") + @pytest.mark.xfail(reason="Unobserved categories included") def test_value_counts(self, all_data, dropna): return super().test_value_counts(all_data, dropna) @@ -184,7 +182,6 @@ def test_combine_add(self, data_repeated): expected = pd.Series([a + val for a in list(orig_data1)]) self.assert_series_equal(result, expected) - @pytest.mark.skip(reason="Not Applicable") def test_fillna_length_mismatch(self, data_missing): super().test_fillna_length_mismatch(data_missing) diff --git a/pandas/tests/extension/test_datetime.py b/pandas/tests/extension/test_datetime.py index a64b42fad9415..92796c604333d 100644 --- a/pandas/tests/extension/test_datetime.py +++ b/pandas/tests/extension/test_datetime.py @@ -175,9 +175,7 @@ class TestMissing(BaseDatetimeTests, base.BaseMissingTests): class TestReshaping(BaseDatetimeTests, base.BaseReshapingTests): - @pytest.mark.skip(reason="We have DatetimeTZBlock") - def test_concat(self, data, in_frame): - pass + pass class TestSetitem(BaseDatetimeTests, base.BaseSetitemTests): diff --git a/pandas/tests/extension/test_interval.py b/pandas/tests/extension/test_interval.py index e2f4d69c489ba..0f916cea9d518 100644 --- a/pandas/tests/extension/test_interval.py +++ b/pandas/tests/extension/test_interval.py @@ -121,9 +121,9 @@ def test_reduce_series_numeric(self, data, all_numeric_reductions, skipna): class TestMethods(BaseInterval, base.BaseMethodsTests): - @pytest.mark.skip(reason="addition is not defined for intervals") + @pytest.mark.xfail(reason="addition is not defined for intervals") def test_combine_add(self, data_repeated): - pass + super().test_combine_add(data_repeated) @pytest.mark.xfail( reason="Raises with incorrect message bc it disallows *all* listlikes " @@ -134,29 +134,31 @@ def test_fillna_length_mismatch(self, data_missing): class TestMissing(BaseInterval, base.BaseMissingTests): - # Index.fillna only accepts scalar `value`, so we have to skip all + # Index.fillna only accepts scalar `value`, so we have to xfail all # non-scalar fill tests. - unsupported_fill = pytest.mark.skip("Unsupported fillna option.") + unsupported_fill = pytest.mark.xfail( + reason="Unsupported fillna option for Interval." + ) @unsupported_fill def test_fillna_limit_pad(self): - pass + super().test_fillna_limit_pad() @unsupported_fill def test_fillna_series_method(self): - pass + super().test_fillna_series_method() @unsupported_fill def test_fillna_limit_backfill(self): - pass + super().test_fillna_limit_backfill() @unsupported_fill def test_fillna_no_op_returns_copy(self): - pass + super().test_fillna_no_op_returns_copy() @unsupported_fill def test_fillna_series(self): - pass + super().test_fillna_series() def test_fillna_non_scalar_raises(self, data_missing): msg = "can only insert Interval objects and NA into an IntervalArray" @@ -173,9 +175,9 @@ class TestSetitem(BaseInterval, base.BaseSetitemTests): class TestPrinting(BaseInterval, base.BasePrintingTests): - @pytest.mark.skip(reason="custom repr") + @pytest.mark.xfail(reason="Interval has custom repr") def test_array_repr(self, data, size): - pass + super().test_array_repr() class TestParsing(BaseInterval, base.BaseParsingTests): diff --git a/pandas/tests/extension/test_numpy.py b/pandas/tests/extension/test_numpy.py index 2e1112ccf2205..a3170d8443e25 100644 --- a/pandas/tests/extension/test_numpy.py +++ b/pandas/tests/extension/test_numpy.py @@ -208,10 +208,9 @@ def test_series_constructor_scalar_with_index(self, data, dtype): class TestDtype(BaseNumPyTests, base.BaseDtypeTests): - @pytest.mark.skip(reason="Incorrect expected.") - # we unsurprisingly clash with a NumPy name. + @pytest.mark.skip(reason="PandasArray expectedly clashes with a NumPy name.") def test_check_dtype(self, data): - pass + super().test_check_dtype(data) class TestGetitem(BaseNumPyTests, base.BaseGetitemTests): @@ -345,11 +344,6 @@ def test_fillna_frame(self, data_missing): class TestReshaping(BaseNumPyTests, base.BaseReshapingTests): - @pytest.mark.skip(reason="Incorrect expected.") - def test_merge(self, data, na_value): - # Fails creating expected (key column becomes a PandasDtype because) - super().test_merge(data, na_value) - @pytest.mark.parametrize( "in_frame", [ diff --git a/pandas/tests/extension/test_string.py b/pandas/tests/extension/test_string.py index 73682620b8353..60d5465dff291 100644 --- a/pandas/tests/extension/test_string.py +++ b/pandas/tests/extension/test_string.py @@ -26,7 +26,7 @@ def split_array(arr): if arr.dtype.storage != "pyarrow": - pytest.skip("chunked array n/a") + pytest.skip("only applicable for pyarrow chunked array n/a") def _split_array(arr): import pyarrow as pa @@ -156,13 +156,9 @@ def test_reduce_series_numeric(self, data, all_numeric_reductions, skipna): class TestMethods(base.BaseMethodsTests): - @pytest.mark.skip(reason="returns nullable") - def test_value_counts(self, all_data, dropna): - return super().test_value_counts(all_data, dropna) - - @pytest.mark.skip(reason="returns nullable") + @pytest.mark.xfail(reason="returns nullable") def test_value_counts_with_normalize(self, data): - pass + super().test_value_counts_with_normalize(data) class TestCasting(base.BaseCastingTests): diff --git a/pandas/tests/plotting/frame/test_frame.py b/pandas/tests/plotting/frame/test_frame.py index 62540a15f47bd..684d8e661d185 100644 --- a/pandas/tests/plotting/frame/test_frame.py +++ b/pandas/tests/plotting/frame/test_frame.py @@ -146,12 +146,11 @@ def test_nullable_int_plot(self): df = DataFrame( { "A": [1, 2, 3, 4, 5], - "B": [1.0, 2.0, 3.0, 4.0, 5.0], - "C": [7, 5, np.nan, 3, 2], + "B": [1, 2, 3, 4, 5], + "C": np.array([7, 5, np.nan, 3, 2], dtype=object), "D": pd.to_datetime(dates, format="%Y").view("i8"), "E": pd.to_datetime(dates, format="%Y", utc=True).view("i8"), - }, - dtype=np.int64, + } ) _check_plot_works(df.plot, x="A", y="B") diff --git a/pandas/tests/plotting/test_converter.py b/pandas/tests/plotting/test_converter.py index 04d3397faddb7..0258d2fae116d 100644 --- a/pandas/tests/plotting/test_converter.py +++ b/pandas/tests/plotting/test_converter.py @@ -327,7 +327,7 @@ def test_conversion(self): rs = self.pc.convert( np.array( - ["2012-01-01 00:00:00+0000", "2012-01-02 00:00:00+0000"], + ["2012-01-01 00:00:00", "2012-01-02 00:00:00"], dtype="datetime64[ns]", ), None, diff --git a/pyproject.toml b/pyproject.toml index ae4072d37a22d..90c1cba90a9aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,7 @@ markers = [ "arm_slow: mark a test as slow for arm64 architecture", "arraymanager: mark a test to run with ArrayManager enabled", ] +asyncio_mode = "strict" [tool.mypy] # Import discovery From ca4293c04f7c455e41a9c25ec691fd070fa2f55e Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Mon, 14 Mar 2022 22:00:04 -0700 Subject: [PATCH 2/4] Remove uncessary super call --- pandas/tests/extension/test_categorical.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/pandas/tests/extension/test_categorical.py b/pandas/tests/extension/test_categorical.py index 5dbccd6bf93b3..1e17bf33c806c 100644 --- a/pandas/tests/extension/test_categorical.py +++ b/pandas/tests/extension/test_categorical.py @@ -149,11 +149,7 @@ class TestIndex(base.BaseIndexTests): class TestMissing(base.BaseMissingTests): - def test_fillna_limit_pad(self, data_missing): - super().test_fillna_limit_pad(data_missing) - - def test_fillna_limit_backfill(self, data_missing): - super().test_fillna_limit_backfill(data_missing) + pass class TestReduce(base.BaseNoReduceTests): @@ -182,9 +178,6 @@ def test_combine_add(self, data_repeated): expected = pd.Series([a + val for a in list(orig_data1)]) self.assert_series_equal(result, expected) - def test_fillna_length_mismatch(self, data_missing): - super().test_fillna_length_mismatch(data_missing) - class TestCasting(base.BaseCastingTests): @pytest.mark.parametrize("cls", [Categorical, CategoricalIndex]) From 6997b497be2b0833df1752626c70dfe7f9f36f37 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Tue, 15 Mar 2022 10:23:47 -0700 Subject: [PATCH 3/4] Address review --- pandas/tests/extension/base/ops.py | 17 +++++++++++------ pandas/tests/extension/test_numpy.py | 10 ++++++++-- pandas/tests/extension/test_string.py | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/pandas/tests/extension/base/ops.py b/pandas/tests/extension/base/ops.py index bdb63a094e5c0..a1d232b737da7 100644 --- a/pandas/tests/extension/base/ops.py +++ b/pandas/tests/extension/base/ops.py @@ -114,17 +114,22 @@ def test_add_series_with_extension_array(self, data): self.assert_series_equal(result, expected) @pytest.mark.parametrize("box", [pd.Series, pd.DataFrame]) - def test_direct_arith_with_ndframe_returns_not_implemented(self, data, box): + def test_direct_arith_with_ndframe_returns_not_implemented( + self, request, data, box + ): # EAs should return NotImplemented for ops with Series/DataFrame # Pandas takes care of unboxing the series and calling the EA's op. other = pd.Series(data) if box is pd.DataFrame: other = other.to_frame() - if hasattr(data, "__add__"): - result = data.__add__(other) - assert result is NotImplemented - else: - pytest.skip(f"{type(data).__name__} does not implement add") + if not hasattr(data, "__add__"): + request.node.add_marker( + pytest.mark.xfail( + reason=f"{type(data).__name__} does not implement add" + ) + ) + result = data.__add__(other) + assert result is NotImplemented class BaseComparisonOpsTests(BaseOpsUtil): diff --git a/pandas/tests/extension/test_numpy.py b/pandas/tests/extension/test_numpy.py index a3170d8443e25..ee181101a181a 100644 --- a/pandas/tests/extension/test_numpy.py +++ b/pandas/tests/extension/test_numpy.py @@ -208,8 +208,14 @@ def test_series_constructor_scalar_with_index(self, data, dtype): class TestDtype(BaseNumPyTests, base.BaseDtypeTests): - @pytest.mark.skip(reason="PandasArray expectedly clashes with a NumPy name.") - def test_check_dtype(self, data): + def test_check_dtype(self, data, request): + if data.dtype.numpy_dtype == "object": + request.node.add_marker( + pytest.mark.xfail( + reason=f"PandasArray expectedly clashes with a " + f"NumPy name: {data.dtype.numpy_dtype}" + ) + ) super().test_check_dtype(data) diff --git a/pandas/tests/extension/test_string.py b/pandas/tests/extension/test_string.py index 60d5465dff291..a4c22e016581d 100644 --- a/pandas/tests/extension/test_string.py +++ b/pandas/tests/extension/test_string.py @@ -156,7 +156,7 @@ def test_reduce_series_numeric(self, data, all_numeric_reductions, skipna): class TestMethods(base.BaseMethodsTests): - @pytest.mark.xfail(reason="returns nullable") + @pytest.mark.xfail(reason="returns nullable: GH 44692") def test_value_counts_with_normalize(self, data): super().test_value_counts_with_normalize(data) From 29c3dcf98dc85147b7e313d862f362c8533fc517 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Tue, 15 Mar 2022 10:52:14 -0700 Subject: [PATCH 4/4] Add pytest asyncio --- azure-pipelines.yml | 2 +- ci/deps/actions-310-numpydev.yaml | 1 + ci/deps/circle-38-arm64.yaml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e6dc98179b7d6..877ea6bc7c44b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -45,7 +45,7 @@ jobs: /opt/python/cp38-cp38/bin/python -m venv ~/virtualenvs/pandas-dev && \ . ~/virtualenvs/pandas-dev/bin/activate && \ python -m pip install --no-deps -U pip wheel 'setuptools<60.0.0' && \ - pip install cython numpy python-dateutil pytz pytest pytest-xdist hypothesis pytest-azurepipelines && \ + pip install cython numpy python-dateutil pytz pytest pytest-xdist pytest-asyncio hypothesis pytest-azurepipelines && \ python setup.py build_ext -q -j2 && \ python -m pip install --no-build-isolation -e . && \ pytest -m 'not slow and not network and not clipboard and not single_cpu' pandas --junitxml=test-data.xml" diff --git a/ci/deps/actions-310-numpydev.yaml b/ci/deps/actions-310-numpydev.yaml index 3e32665d5433f..a5eb8a69e19da 100644 --- a/ci/deps/actions-310-numpydev.yaml +++ b/ci/deps/actions-310-numpydev.yaml @@ -9,6 +9,7 @@ dependencies: - pytest-cov - pytest-xdist>=1.31 - hypothesis>=5.5.3 + - pytest-asyncio # pandas dependencies - python-dateutil diff --git a/ci/deps/circle-38-arm64.yaml b/ci/deps/circle-38-arm64.yaml index 60608c3ee1a86..7e5b56ebe081f 100644 --- a/ci/deps/circle-38-arm64.yaml +++ b/ci/deps/circle-38-arm64.yaml @@ -9,6 +9,7 @@ dependencies: - pytest>=6.0 - pytest-xdist>=1.31 - hypothesis>=5.5.3 + - pytest-asyncio # pandas dependencies - botocore>=1.11