From 4a081f5540b8163c3165c718472696ba9775a43d Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:49:19 -0700 Subject: [PATCH 1/2] TST: More explicit test patters --- pandas/tests/arithmetic/test_datetime64.py | 10 ++--- pandas/tests/arithmetic/test_numeric.py | 2 +- pandas/tests/arithmetic/test_timedelta64.py | 2 +- pandas/tests/frame/methods/test_to_csv.py | 5 +-- pandas/tests/frame/test_arithmetic.py | 10 +++-- pandas/tests/frame/test_constructors.py | 2 +- pandas/tests/groupby/test_api.py | 3 +- .../tests/groupby/transform/test_transform.py | 8 +--- pandas/tests/indexes/multi/test_setops.py | 3 +- pandas/tests/indexes/test_any_index.py | 2 +- pandas/tests/indexes/test_base.py | 8 ++-- pandas/tests/indexes/test_common.py | 10 +++-- pandas/tests/indexes/test_index_new.py | 5 ++- pandas/tests/indexes/test_indexing.py | 7 ++-- pandas/tests/indexes/test_numpy_compat.py | 2 +- pandas/tests/indexes/test_old_base.py | 39 +++++++------------ pandas/tests/indexes/test_setops.py | 14 +++---- pandas/tests/indexing/multiindex/test_loc.py | 5 +-- pandas/tests/indexing/test_loc.py | 2 +- pandas/tests/io/xml/test_xml.py | 2 +- pandas/tests/plotting/test_converter.py | 4 +- pandas/tests/plotting/test_datetimelike.py | 22 ++++++----- .../reshape/concat/test_append_common.py | 7 +--- pandas/tests/reshape/concat/test_empty.py | 2 +- pandas/tests/reshape/merge/test_merge_asof.py | 9 ++--- pandas/tests/scalar/test_nat.py | 7 ++-- pandas/tests/series/indexing/test_setitem.py | 13 +++---- pandas/tests/series/methods/test_clip.py | 2 +- pandas/tests/series/test_logical_ops.py | 4 +- pandas/tests/test_expressions.py | 19 ++++----- pandas/tests/tools/test_to_datetime.py | 20 +++++----- pandas/tests/window/test_ewm.py | 2 +- 32 files changed, 117 insertions(+), 135 deletions(-) diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py index 01217f87b6359..34b526bf97408 100644 --- a/pandas/tests/arithmetic/test_datetime64.py +++ b/pandas/tests/arithmetic/test_datetime64.py @@ -414,8 +414,7 @@ def test_dti_cmp_datetimelike(self, other, tz_naive_fixture): dti = date_range("2016-01-01", periods=2, tz=tz) if tz is not None: if isinstance(other, np.datetime64): - # no tzaware version available - return + pytest.skip("no tzaware version available") other = localize_pydatetime(other, dti.tzinfo) result = dti == other @@ -1080,13 +1079,14 @@ def test_dt64arr_add_dtlike_raises(self, tz_naive_fixture, box_with_array): @pytest.mark.parametrize("freq", ["H", "D", "W", "M", "MS", "Q", "B", None]) @pytest.mark.parametrize("dtype", [None, "uint8"]) def test_dt64arr_addsub_intlike( - self, dtype, box_with_array, freq, tz_naive_fixture + self, request, dtype, box_with_array, freq, tz_naive_fixture ): # GH#19959, GH#19123, GH#19012 tz = tz_naive_fixture if box_with_array is pd.DataFrame: - # alignment headaches - return + request.node.add_marker( + pytest.mark.xfail(raises=ValueError, reason="Axis alignment fails") + ) if freq is None: dti = DatetimeIndex(["NaT", "2017-04-05 06:07:08"], tz=tz) diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py index 7f0996da2e2f2..fa17c24fffb26 100644 --- a/pandas/tests/arithmetic/test_numeric.py +++ b/pandas/tests/arithmetic/test_numeric.py @@ -377,7 +377,7 @@ def test_divmod_zero(self, zero, numeric_idx): def test_div_negative_zero(self, zero, numeric_idx, op): # Check that -1 / -0.0 returns np.inf, not -np.inf if numeric_idx.dtype == np.uint64: - return + pytest.skip(f"Not relevant for {numeric_idx.dtype}") idx = numeric_idx - 3 expected = Index([-np.inf, -np.inf, -np.inf, np.nan, np.inf], dtype=np.float64) diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py index 0ffe1ddc3dfb7..3d237b3ac4a31 100644 --- a/pandas/tests/arithmetic/test_timedelta64.py +++ b/pandas/tests/arithmetic/test_timedelta64.py @@ -1002,7 +1002,7 @@ def test_td64arr_add_sub_datetimelike_scalar( ts = dt_scalar.to_pydatetime() elif cls is np.datetime64: if tz_naive_fixture is not None: - return + pytest.skip(f"{cls} doesn support {tz_naive_fixture}") ts = dt_scalar.to_datetime64() else: ts = dt_scalar diff --git a/pandas/tests/frame/methods/test_to_csv.py b/pandas/tests/frame/methods/test_to_csv.py index bbd6a4bb1ec6c..294da02e259b7 100644 --- a/pandas/tests/frame/methods/test_to_csv.py +++ b/pandas/tests/frame/methods/test_to_csv.py @@ -674,10 +674,7 @@ def create_cols(name): # add in some nans df_float.iloc[30:50, 1:3] = np.nan - - # ## this is a bug in read_csv right now #### - # df_dt.loc[30:50,1:3] = np.nan - # FIXME: don't leave commented-out + df_dt.iloc[30:50, 1:3] = np.nan df = pd.concat([df_float, df_int, df_bool, df_object, df_dt], axis=1) diff --git a/pandas/tests/frame/test_arithmetic.py b/pandas/tests/frame/test_arithmetic.py index 262ed69ca7099..878e94c15e16b 100644 --- a/pandas/tests/frame/test_arithmetic.py +++ b/pandas/tests/frame/test_arithmetic.py @@ -1766,7 +1766,12 @@ def test_inplace_ops_identity(self): [ "add", "and", - "div", + pytest.param( + "div", + marks=pytest.mark.xfail( + raises=AttributeError, reason="__idiv__ not implemented" + ), + ), "floordiv", "mod", "mul", @@ -1778,9 +1783,6 @@ def test_inplace_ops_identity(self): ], ) def test_inplace_ops_identity2(self, op): - if op == "div": - return - df = DataFrame({"a": [1.0, 2.0, 3.0], "b": [1, 2, 3]}) operand = 2 diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index c8b67675b7798..1c8ce4e1871ac 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -2514,7 +2514,7 @@ def test_dict_nocopy( b = np.array([3, 4], dtype=any_numpy_dtype) if b.dtype.kind in ["S", "U"]: # These get cast, making the checks below more cumbersome - return + pytest.skip(f"{b.dtype} get cast, making the checks below more cumbersome") c = pd.array([1, 2], dtype=any_numeric_ea_dtype) c_orig = c.copy() diff --git a/pandas/tests/groupby/test_api.py b/pandas/tests/groupby/test_api.py index 1122403be877f..1a030841ba3ab 100644 --- a/pandas/tests/groupby/test_api.py +++ b/pandas/tests/groupby/test_api.py @@ -205,8 +205,7 @@ def test_frame_consistency(groupby_func): def test_series_consistency(request, groupby_func): # GH#48028 if groupby_func in ("first", "last"): - # first and last are entirely different between Series and groupby - return + pytest.skip("first and last are entirely different between Series and groupby") if groupby_func in ("cumcount", "corrwith", "ngroup"): assert not hasattr(Series, groupby_func) diff --git a/pandas/tests/groupby/transform/test_transform.py b/pandas/tests/groupby/transform/test_transform.py index bd71b32603e68..826e1d501a2c4 100644 --- a/pandas/tests/groupby/transform/test_transform.py +++ b/pandas/tests/groupby/transform/test_transform.py @@ -775,9 +775,7 @@ def frame_mi(frame): {"by": np.random.default_rng(2).integers(0, 50, size=10).astype(float)}, {"level": 0}, {"by": "string"}, - # {"by": 'string_missing'}]: - # {"by": ['int','string']}]: - # TODO: remove or enable commented-out code + {"by": ["int", "string"]}, ], ) def test_cython_transform_frame(request, op, args, targop, df_fix, gb_target): @@ -825,9 +823,7 @@ def test_cython_transform_frame(request, op, args, targop, df_fix, gb_target): {"by": np.random.default_rng(2).integers(0, 50, size=10).astype(float)}, {"level": 0}, {"by": "string"}, - # {"by": 'string_missing'}]: - # {"by": ['int','string']}]: - # TODO: remove or enable commented-out code + {"by": ["int", "string"]}, ], ) @pytest.mark.parametrize( diff --git a/pandas/tests/indexes/multi/test_setops.py b/pandas/tests/indexes/multi/test_setops.py index 29f9295513c31..c951403fb2654 100644 --- a/pandas/tests/indexes/multi/test_setops.py +++ b/pandas/tests/indexes/multi/test_setops.py @@ -626,8 +626,7 @@ def test_union_with_duplicates_keep_ea_dtype(dupe_val, any_numeric_ea_dtype): def test_union_duplicates(index, request): # GH#38977 if index.empty or isinstance(index, (IntervalIndex, CategoricalIndex)): - # No duplicates in empty indexes - return + pytest.skip(f"No duplicates in an empty {type(index).__name__}") values = index.unique().values.tolist() mi1 = MultiIndex.from_arrays([values, [1] * len(values)]) diff --git a/pandas/tests/indexes/test_any_index.py b/pandas/tests/indexes/test_any_index.py index 8a951c3c38be6..10204cfb78e89 100644 --- a/pandas/tests/indexes/test_any_index.py +++ b/pandas/tests/indexes/test_any_index.py @@ -34,7 +34,7 @@ def test_hash_error(index): def test_mutability(index): if not len(index): - return + pytest.skip("Test doesn't make sense for empty index") msg = "Index does not support mutable operations" with pytest.raises(TypeError, match=msg): index[0] = index[0] diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 19711ba6329d4..cdef8f2cdd917 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -561,11 +561,9 @@ def test_map_dictlike_simple(self, mapper): def test_map_dictlike(self, index, mapper, request): # GH 12756 if isinstance(index, CategoricalIndex): - # Tested in test_categorical - return + pytest.skip("Tested in test_categorical") elif not index.is_unique: - # Cannot map duplicated index - return + pytest.skip("Cannot map duplicated index") rng = np.arange(len(index), 0, -1, dtype=np.int64) @@ -785,7 +783,7 @@ def test_drop_tuple(self, values, to_drop): def test_drop_with_duplicates_in_index(self, index): # GH38051 if len(index) == 0 or isinstance(index, MultiIndex): - return + pytest.skip("Test doesn't make sense for empty MultiIndex") if isinstance(index, IntervalIndex) and not IS64: pytest.skip("Cannot test IntervalIndex with int64 dtype on 32 bit platform") index = index.unique().repeat(2) diff --git a/pandas/tests/indexes/test_common.py b/pandas/tests/indexes/test_common.py index 05834b02a5ff3..6245a129afedc 100644 --- a/pandas/tests/indexes/test_common.py +++ b/pandas/tests/indexes/test_common.py @@ -121,10 +121,6 @@ def test_set_name_methods(self, index_flat): assert res is None assert index.name == new_name assert index.names == [new_name] - # FIXME: dont leave commented-out - # with pytest.raises(TypeError, match="list-like"): - # # should still fail even if it would be the right length - # ind.set_names("a") with pytest.raises(ValueError, match="Level must be None"): index.set_names("a", level=0) @@ -134,6 +130,12 @@ def test_set_name_methods(self, index_flat): assert index.name == name assert index.names == [name] + @pytest.mark.xfail + def test_set_names_single_label_no_level(self, index_flat): + with pytest.raises(TypeError, match="list-like"): + # should still fail even if it would be the right length + index_flat.set_names("a") + def test_copy_and_deepcopy(self, index_flat): index = index_flat diff --git a/pandas/tests/indexes/test_index_new.py b/pandas/tests/indexes/test_index_new.py index 564d3abc4f1fe..d35c35661051a 100644 --- a/pandas/tests/indexes/test_index_new.py +++ b/pandas/tests/indexes/test_index_new.py @@ -132,7 +132,10 @@ def test_constructor_infer_nat_dt_like( ): if isinstance(nulls_fixture, Decimal): # We dont cast these to datetime64/timedelta64 - return + pytest.skip( + f"We don't cast {type(nulls_fixture).__name__} to " + "datetime64/timedelta64" + ) expected = klass([NaT, NaT]) assert expected.dtype == dtype diff --git a/pandas/tests/indexes/test_indexing.py b/pandas/tests/indexes/test_indexing.py index 26c92e1f93865..1ea47f636ac9b 100644 --- a/pandas/tests/indexes/test_indexing.py +++ b/pandas/tests/indexes/test_indexing.py @@ -56,8 +56,7 @@ def test_take_invalid_kwargs(self, index): def test_take(self, index): indexer = [4, 3, 0, 2] if len(index) < 5: - # not enough elements; ignore - return + pytest.skip("Test doesn't make sense since not enough elements") result = index.take(indexer) expected = index[indexer] @@ -81,7 +80,7 @@ def test_take_minus1_without_fill(self, index): # -1 does not get treated as NA unless allow_fill=True is passed if len(index) == 0: # Test is not applicable - return + pytest.skip("Test doesn't make sense for empty index") result = index.take([0, 0, -1]) @@ -289,7 +288,7 @@ class TestPutmask: def test_putmask_with_wrong_mask(self, index): # GH#18368 if not len(index): - return + pytest.skip("Test doesn't make sense for empty index") fill = index[0] diff --git a/pandas/tests/indexes/test_numpy_compat.py b/pandas/tests/indexes/test_numpy_compat.py index 5e2e2b9bbec21..ace78d77350cb 100644 --- a/pandas/tests/indexes/test_numpy_compat.py +++ b/pandas/tests/indexes/test_numpy_compat.py @@ -154,7 +154,7 @@ def test_numpy_ufuncs_other(index, func): def test_numpy_ufuncs_reductions(index, func, request): # TODO: overlap with tests.series.test_ufunc.test_reductions if len(index) == 0: - return + pytest.skip("Test doesn't make sense for empty index.") if isinstance(index, CategoricalIndex) and index.dtype.ordered is False: with pytest.raises(TypeError, match="is not ordered for"): diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 3b627f2fae845..f8f5a543a9c19 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -167,7 +167,7 @@ def test_numeric_compat(self, simple_index): # we can remove multi.test_compat.test_numeric_compat assert not isinstance(idx, MultiIndex) if type(idx) is Index: - return + pytest.skip("Not applicable for Index") if is_numeric_dtype(simple_index.dtype) or isinstance( simple_index, TimedeltaIndex ): @@ -246,9 +246,10 @@ def test_ensure_copied_data(self, index): # Needs "freq" specification: init_kwargs["freq"] = index.freq elif isinstance(index, (RangeIndex, MultiIndex, CategoricalIndex)): - # RangeIndex cannot be initialized from data - # MultiIndex and CategoricalIndex are tested separately - return + pytest.skip( + "RangeIndex cannot be initialized from data, " + "MultiIndex and CategoricalIndex are tested separately" + ) elif index.dtype == object and index.inferred_type == "boolean": init_kwargs["dtype"] = index.dtype @@ -319,9 +320,8 @@ def test_memory_usage(self, index): assert result3 > result2 def test_argsort(self, index): - # separately tested if isinstance(index, CategoricalIndex): - return + pytest.skip(f"{type(self).__name__} separately tested") result = index.argsort() expected = np.array(index).argsort() @@ -400,7 +400,7 @@ def test_insert_base(self, index): result = index[1:4] if not len(index): - return + pytest.skip("Not applicable for empty index") # test 0th element assert index[0:4].equals(result.insert(0, index[0])) @@ -434,11 +434,11 @@ def test_insert_out_of_bounds(self, index): def test_delete_base(self, index): if not len(index): - return + pytest.skip("Not applicable for empty index") if isinstance(index, RangeIndex): # tested in class - return + pytest.skip(f"{type(self).__name__} tested elsewhere") expected = index[1:] result = index.delete(0) @@ -458,9 +458,7 @@ def test_delete_base(self, index): @pytest.mark.filterwarnings(r"ignore:PeriodDtype\[B\] is deprecated:FutureWarning") def test_equals(self, index): if isinstance(index, IntervalIndex): - # IntervalIndex tested separately, the index.equals(index.astype(object)) - # fails for IntervalIndex - return + pytest.skip(f"{type(index).__name__} tested elsewhere") is_ea_idx = type(index) is Index and not isinstance(index.dtype, np.dtype) @@ -566,12 +564,11 @@ def test_format_empty(self, simple_index): def test_fillna(self, index): # GH 11343 if len(index) == 0: - return + pytest.skip("Not relevant for empty index") elif index.dtype == bool: - # can't hold NAs - return + pytest.skip(f"{index.dtype} cannot hold NAs") elif isinstance(index, Index) and is_integer_dtype(index.dtype): - return + pytest.skip(f"Not relevant for Index with {index.dtype}") elif isinstance(index, MultiIndex): idx = index.copy(deep=True) msg = "isna is not defined for MultiIndex" @@ -654,15 +651,9 @@ def test_map(self, simple_index): ], ) @pytest.mark.filterwarnings(r"ignore:PeriodDtype\[B\] is deprecated:FutureWarning") - def test_map_dictlike(self, mapper, simple_index): + def test_map_dictlike(self, mapper, simple_index, request): idx = simple_index - if isinstance(idx, CategoricalIndex): - # FIXME: this fails with CategoricalIndex bc it goes through - # Categorical.map which ends up calling get_indexer with - # non-unique values, which raises. This _should_ work fine for - # CategoricalIndex. - pytest.skip(f"skipping tests for {type(idx)}") - elif isinstance(idx, (DatetimeIndex, TimedeltaIndex, PeriodIndex)): + if isinstance(idx, (DatetimeIndex, TimedeltaIndex, PeriodIndex)): pytest.skip("Tested elsewhere.") identity = mapper(idx.values, idx) diff --git a/pandas/tests/indexes/test_setops.py b/pandas/tests/indexes/test_setops.py index 31a867acdb5d1..2fd203dbc77ed 100644 --- a/pandas/tests/indexes/test_setops.py +++ b/pandas/tests/indexes/test_setops.py @@ -194,7 +194,7 @@ def test_set_ops_error_cases(self, case, method, index): @pytest.mark.filterwarnings(r"ignore:PeriodDtype\[B\] is deprecated:FutureWarning") def test_intersection_base(self, index): if isinstance(index, CategoricalIndex): - return + pytest.skip(f"Not relevant for {type(index).__name__}") first = index[:5] second = index[:3] @@ -280,13 +280,13 @@ def test_difference_base(self, sort, index): ) def test_symmetric_difference(self, index): if isinstance(index, CategoricalIndex): - return + pytest.skip(f"Not relevant for {type(index).__name__}") if len(index) < 2: - return + pytest.skip("Too few values for test") if index[0] in index[1:] or index[-1] in index[:-1]: # index fixture has e.g. an index of bools that does not satisfy this, # another with [0, 0, 1, 1, 2, 2] - return + pytest.skip("Index values no not satisfy test condition.") first = index[1:] second = index[:-1] @@ -465,7 +465,7 @@ def test_difference_preserves_type_empty(self, index, sort): # If taking difference of a set and itself, it # needs to preserve the type of the index if not index.is_unique: - return + pytest.skip("Not relevant since index is not unique") result = index.difference(index, sort=sort) expected = index[:0] tm.assert_index_equal(result, expected, exact=True) @@ -488,7 +488,7 @@ def test_intersection_difference_match_empty(self, index, sort): # empty index produces the same index as the difference # of an index with itself. Test for all types if not index.is_unique: - return + pytest.skip("Not relevant because index is not unique") inter = index.intersection(index[:0]) diff = index.difference(index, sort=sort) tm.assert_index_equal(inter, diff, exact=True) @@ -521,7 +521,7 @@ def test_intersection_duplicates_all_indexes(index): # GH#38743 if index.empty: # No duplicates in empty indexes - return + pytest.skip("Not relevant for empty Index") idx = index idx_non_unique = idx[[0, 0, 1, 2]] diff --git a/pandas/tests/indexing/multiindex/test_loc.py b/pandas/tests/indexing/multiindex/test_loc.py index f5369f23bfd19..c8b10f72c9ad9 100644 --- a/pandas/tests/indexing/multiindex/test_loc.py +++ b/pandas/tests/indexing/multiindex/test_loc.py @@ -620,9 +620,8 @@ def test_loc_period_string_indexing(): # not a slice assert np.isnan(result) - # TODO: should it figure this out? - # alt = df.loc["2013Q1", 1111, "OMS"] - # assert np.isnan(alt) + alt = df.loc[("2013Q1", 1111), "OMS"] + assert np.isnan(alt) def test_loc_datetime_mask_slicing(): diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 8524529ecc4b0..b314c20568f64 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -2099,7 +2099,7 @@ def test_loc_setitem_with_expansion_inf_upcast_empty(self): def test_loc_setitem_with_expansion_nonunique_index(self, index): # GH#40096 if not len(index): - return + pytest.skip("Not relevant for empty Index") index = index.repeat(2) # ensure non-unique N = len(index) diff --git a/pandas/tests/io/xml/test_xml.py b/pandas/tests/io/xml/test_xml.py index d36fcdc0f4431..88655483800ee 100644 --- a/pandas/tests/io/xml/test_xml.py +++ b/pandas/tests/io/xml/test_xml.py @@ -1958,7 +1958,7 @@ def test_wrong_compression(parser, compression, compression_only): attempted_compression = compression_only if actual_compression == attempted_compression: - return + pytest.skip(f"{actual_compression} == {attempted_compression}") errors = { "bz2": (OSError, "Invalid data stream"), diff --git a/pandas/tests/plotting/test_converter.py b/pandas/tests/plotting/test_converter.py index cadd4c4589964..56d7900e2907d 100644 --- a/pandas/tests/plotting/test_converter.py +++ b/pandas/tests/plotting/test_converter.py @@ -386,8 +386,8 @@ def test_quarterly_finder(year_span): vmin = -1000 vmax = vmin + year_span * 4 span = vmax - vmin + 1 - if span < 45: # the quarterly finder is only invoked if the span is >= 45 - return + if span < 45: + pytest.skip("the quarterly finder is only invoked if the span is >= 45") nyears = span / 4 (min_anndef, maj_anndef) = converter._get_default_annual_spacing(nyears) result = converter._quarterly_finder(vmin, vmax, "Q") diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index af5a0364e0681..b3ae25ac9168f 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -882,21 +882,25 @@ def test_mixed_freq_shared_ax_twin_x(self): s1 = Series(range(len(idx1)), idx1) s2 = Series(range(len(idx2)), idx2) # using twinx - fig, ax1 = mpl.pyplot.subplots() + _, ax1 = mpl.pyplot.subplots() ax2 = ax1.twinx() s1.plot(ax=ax1) s2.plot(ax=ax2) assert ax1.lines[0].get_xydata()[0, 0] == ax2.lines[0].get_xydata()[0, 0] - # TODO (GH14330, GH14322) - # plotting the irregular first does not yet work - # fig, ax1 = plt.subplots() - # ax2 = ax1.twinx() - # s2.plot(ax=ax1) - # s1.plot(ax=ax2) - # assert (ax1.lines[0].get_xydata()[0, 0] == - # ax2.lines[0].get_xydata()[0, 0]) + @pytest.mark.xfail(reason="TODO (GH14330, GH14322)") + def test_mixed_freq_shared_ax_twin_x_irregular_first(self): + # GH13341, using sharex=True + idx1 = date_range("2015-01-01", periods=3, freq="M") + idx2 = idx1[:1].union(idx1[2:]) + s1 = Series(range(len(idx1)), idx1) + s2 = Series(range(len(idx2)), idx2) + _, ax1 = mpl.pyplot.subplots() + ax2 = ax1.twinx() + s2.plot(ax=ax1) + s1.plot(ax=ax2) + assert ax1.lines[0].get_xydata()[0, 0] == ax2.lines[0].get_xydata()[0, 0] def test_nat_handling(self): _, ax = mpl.pyplot.subplots() diff --git a/pandas/tests/reshape/concat/test_append_common.py b/pandas/tests/reshape/concat/test_append_common.py index 6130960568b73..df5ca2f27c15d 100644 --- a/pandas/tests/reshape/concat/test_append_common.py +++ b/pandas/tests/reshape/concat/test_append_common.py @@ -187,12 +187,9 @@ def test_concatlike_dtypes_coercion(self, item, item2, request): exp_series_dtype = None if typ1 == typ2: - # same dtype is tested in test_concatlike_same_dtypes - return + pytest.skip("same dtype is tested in test_concatlike_same_dtypes") elif typ1 == "category" or typ2 == "category": - # The `vals1 + vals2` below fails bc one of these is a Categorical - # instead of a list; we have separate dedicated tests for categorical - return + pytest.skip("categorical type tested elsewhere") # specify expected dtype if typ1 == "bool" and typ2 in ("int64", "float64"): diff --git a/pandas/tests/reshape/concat/test_empty.py b/pandas/tests/reshape/concat/test_empty.py index 573b945e24d38..c80f3244dccaf 100644 --- a/pandas/tests/reshape/concat/test_empty.py +++ b/pandas/tests/reshape/concat/test_empty.py @@ -137,7 +137,7 @@ def test_concat_empty_series_dtypes_match_roundtrips(self, dtype): def test_concat_empty_series_dtypes_roundtrips(self, dtype, dtype2): # round-tripping with self & like self if dtype == dtype2: - return + pytest.skip("same dtype is not applicable for test") def int_result_type(dtype, dtype2): typs = {dtype.kind, dtype2.kind} diff --git a/pandas/tests/reshape/merge/test_merge_asof.py b/pandas/tests/reshape/merge/test_merge_asof.py index 2ea6077dc2481..d4cb89dadde9b 100644 --- a/pandas/tests/reshape/merge/test_merge_asof.py +++ b/pandas/tests/reshape/merge/test_merge_asof.py @@ -1382,19 +1382,18 @@ def test_timedelta_tolerance_nearest(self, unit): tm.assert_frame_equal(result, expected) - # TODO: any_int_dtype; causes failures in _get_join_indexers - def test_int_type_tolerance(self, any_int_numpy_dtype): + def test_int_type_tolerance(self, any_int_dtype): # GH #28870 left = pd.DataFrame({"a": [0, 10, 20], "left_val": [1, 2, 3]}) right = pd.DataFrame({"a": [5, 15, 25], "right_val": [1, 2, 3]}) - left["a"] = left["a"].astype(any_int_numpy_dtype) - right["a"] = right["a"].astype(any_int_numpy_dtype) + left["a"] = left["a"].astype(any_int_dtype) + right["a"] = right["a"].astype(any_int_dtype) expected = pd.DataFrame( {"a": [0, 10, 20], "left_val": [1, 2, 3], "right_val": [np.nan, 1.0, 2.0]} ) - expected["a"] = expected["a"].astype(any_int_numpy_dtype) + expected["a"] = expected["a"].astype(any_int_dtype) result = merge_asof(left, right, on="a", tolerance=10) tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py index 6f163b7ecd89d..f5a94099523fb 100644 --- a/pandas/tests/scalar/test_nat.py +++ b/pandas/tests/scalar/test_nat.py @@ -311,14 +311,15 @@ def test_nat_doc_strings(compare): klass, method = compare klass_doc = getattr(klass, method).__doc__ - # Ignore differences with Timestamp.isoformat() as they're intentional if klass == Timestamp and method == "isoformat": - return + pytest.skip( + "Ignore differences with Timestamp.isoformat() as they're intentional" + ) if method == "to_numpy": # GH#44460 can return either dt64 or td64 depending on dtype, # different docstring is intentional - return + pytest.skip(f"different docstring for {method} is intentional") nat_doc = getattr(NaT, method).__doc__ assert klass_doc == nat_doc diff --git a/pandas/tests/series/indexing/test_setitem.py b/pandas/tests/series/indexing/test_setitem.py index f1e66212c131a..bc596fb0a3abe 100644 --- a/pandas/tests/series/indexing/test_setitem.py +++ b/pandas/tests/series/indexing/test_setitem.py @@ -422,11 +422,10 @@ def test_setitem_mask_smallint_no_upcast(self): ser2.mask(mask, alt, inplace=True) tm.assert_series_equal(ser2, expected) - # FIXME: don't leave commented-out - # FIXME: ser.where(~mask, alt) unnecessarily upcasts to int64 - # ser3 = orig.copy() - # res = ser3.where(~mask, alt) - # tm.assert_series_equal(res, expected) + # TODO: ser.where(~mask, alt) unnecessarily upcasts to int64 + ser3 = orig.copy() + res = ser3.where(~mask, alt) + tm.assert_series_equal(res, expected, check_dtype=False) class TestSetitemViewCopySemantics: @@ -750,7 +749,7 @@ def _check_inplace(self, is_inplace, orig, arr, obj): def test_int_key(self, obj, key, expected, warn, val, indexer_sli, is_inplace): if not isinstance(key, int): - return + pytest.skip("Not relevant for int key") with tm.assert_produces_warning(warn, match="incompatible dtype"): self.check_indexer(obj, key, expected, val, indexer_sli, is_inplace) @@ -786,7 +785,7 @@ def test_int_key(self, obj, key, expected, warn, val, indexer_sli, is_inplace): def test_slice_key(self, obj, key, expected, warn, val, indexer_sli, is_inplace): if not isinstance(key, slice): - return + pytest.skip("Not relevant for slice key") if indexer_sli is not tm.loc: # Note: no .loc because that handles slice edges differently diff --git a/pandas/tests/series/methods/test_clip.py b/pandas/tests/series/methods/test_clip.py index c88a42697dbdf..da144261ea5b4 100644 --- a/pandas/tests/series/methods/test_clip.py +++ b/pandas/tests/series/methods/test_clip.py @@ -48,7 +48,7 @@ def test_series_clipping_with_na_values(self, any_numeric_ea_dtype, nulls_fixtur if nulls_fixture is pd.NaT: # constructor will raise, see # test_constructor_mismatched_null_nullable_dtype - return + pytest.skip("See test_constructor_mismatched_null_nullable_dtype") ser = Series([nulls_fixture, 1.0, 3.0], dtype=any_numeric_ea_dtype) s_clipped_upper = ser.clip(upper=2.0) diff --git a/pandas/tests/series/test_logical_ops.py b/pandas/tests/series/test_logical_ops.py index 19412db91b487..4dab3e8f62598 100644 --- a/pandas/tests/series/test_logical_ops.py +++ b/pandas/tests/series/test_logical_ops.py @@ -304,9 +304,7 @@ def test_logical_ops_with_index(self, op): def test_reversed_xor_with_index_returns_series(self): # GH#22092, GH#19792 pre-2.0 these were aliased to setops ser = Series([True, True, False, False]) - idx1 = Index( - [True, False, True, False], dtype=object - ) # TODO: raises if bool-dtype + idx1 = Index([True, False, True, False], dtype=bool) idx2 = Index([1, 0, 1, 0]) expected = Series([False, True, True, False]) diff --git a/pandas/tests/test_expressions.py b/pandas/tests/test_expressions.py index 17dfa95b66201..1e66cefbcfdd0 100644 --- a/pandas/tests/test_expressions.py +++ b/pandas/tests/test_expressions.py @@ -188,11 +188,9 @@ def test_run_binary(self, request, fixture, flex, comparison_op): assert used_numexpr, "Did not use numexpr as expected." tm.assert_equal(expected, result) - # FIXME: dont leave commented-out - # series doesn't uses vec_compare instead of numexpr... - # for i in range(len(df.columns)): - # binary_comp = other.iloc[:, i] + 1 - # self.run_binary(df.iloc[:, i], binary_comp, flex) + for i in range(len(df.columns)): + binary_comp = other.iloc[:, i] + 1 + self.call_op(df.iloc[:, i], binary_comp, flex, "add") def test_invalid(self): array = np.random.default_rng(2).standard_normal(1_000_001) @@ -222,10 +220,9 @@ def test_binary_ops(self, request, opname, op_str, left_fix, right_fix): left = request.getfixturevalue(left_fix) right = request.getfixturevalue(right_fix) - def testit(): + def testit(left, right, opname, op_str): if opname == "pow": - # TODO: get this working - return + left = np.abs(left) op = getattr(operator, opname) @@ -238,12 +235,12 @@ def testit(): assert not result with option_context("compute.use_numexpr", False): - testit() + testit(left, right, opname, op_str) expr.set_numexpr_threads(1) - testit() + testit(left, right, opname, op_str) expr.set_numexpr_threads() - testit() + testit(left, right, opname, op_str) @pytest.mark.parametrize( "left_fix,right_fix", [("_array", "_array2"), ("_array_mixed", "_array_mixed2")] diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py index 83b4949bc32cd..5e51edfee17f1 100644 --- a/pandas/tests/tools/test_to_datetime.py +++ b/pandas/tests/tools/test_to_datetime.py @@ -1818,7 +1818,7 @@ def test_to_datetime_mixed_offsets_with_utc_false_deprecated(self, date): class TestToDatetimeUnit: @pytest.mark.parametrize("unit", ["Y", "M"]) @pytest.mark.parametrize("item", [150, float(150)]) - def test_to_datetime_month_or_year_unit_int(self, cache, unit, item): + def test_to_datetime_month_or_year_unit_int(self, cache, unit, item, request): # GH#50870 Note we have separate tests that pd.Timestamp gets these right ts = Timestamp(item, unit=unit) expected = DatetimeIndex([ts]) @@ -1826,13 +1826,19 @@ def test_to_datetime_month_or_year_unit_int(self, cache, unit, item): result = to_datetime([item], unit=unit, cache=cache) tm.assert_index_equal(result, expected) - # TODO: this should also work - # result = to_datetime(np.array([item]), unit=unit, cache=cache) - # tm.assert_index_equal(result, expected) - result = to_datetime(np.array([item], dtype=object), unit=unit, cache=cache) tm.assert_index_equal(result, expected) + # TODO: this should also work + if isinstance(item, float): + request.node.add_marker( + pytest.mark.xfail( + reason=f"{type(item).__name__} in np.array should work" + ) + ) + result = to_datetime(np.array([item]), unit=unit, cache=cache) + tm.assert_index_equal(result, expected) + @pytest.mark.parametrize("unit", ["Y", "M"]) def test_to_datetime_month_or_year_unit_non_round_float(self, cache, unit): # GH#50301 @@ -1850,10 +1856,6 @@ def test_to_datetime_month_or_year_unit_non_round_float(self, cache, unit): # constructor; this may not be ideal with pytest.raises(ValueError, match=msg): to_datetime([1.5], unit=unit, errors="ignore") - # TODO: we are NOT consistent with the Timestamp behavior in the - # float-like string case - # with pytest.raises(ValueError, match=msg): - # to_datetime(["1.5"], unit=unit, errors="ignore") res = to_datetime([1.5], unit=unit, errors="coerce") expected = Index([NaT], dtype="M8[ns]") diff --git a/pandas/tests/window/test_ewm.py b/pandas/tests/window/test_ewm.py index c510bf8d51e09..45d481fdd2e44 100644 --- a/pandas/tests/window/test_ewm.py +++ b/pandas/tests/window/test_ewm.py @@ -690,7 +690,7 @@ def test_numeric_only_series(arithmetic_win_operators, numeric_only, dtype): op = getattr(ewm, kernel, None) if op is None: # Nothing to test - return + pytest.skip("No op to test") if numeric_only and dtype is object: msg = f"ExponentialMovingWindow.{kernel} does not implement numeric_only" with pytest.raises(NotImplementedError, match=msg): From 383ac1cb83a6caa57bb06ad5d77707956b34e428 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Wed, 9 Aug 2023 08:57:56 -0700 Subject: [PATCH 2/2] Add back string_missing --- pandas/tests/groupby/transform/test_transform.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/tests/groupby/transform/test_transform.py b/pandas/tests/groupby/transform/test_transform.py index 826e1d501a2c4..062dfe3931423 100644 --- a/pandas/tests/groupby/transform/test_transform.py +++ b/pandas/tests/groupby/transform/test_transform.py @@ -775,6 +775,7 @@ def frame_mi(frame): {"by": np.random.default_rng(2).integers(0, 50, size=10).astype(float)}, {"level": 0}, {"by": "string"}, + pytest.param({"by": "string_missing"}, marks=pytest.mark.xfail), {"by": ["int", "string"]}, ], ) @@ -823,6 +824,8 @@ def test_cython_transform_frame(request, op, args, targop, df_fix, gb_target): {"by": np.random.default_rng(2).integers(0, 50, size=10).astype(float)}, {"level": 0}, {"by": "string"}, + # TODO: create xfail condition given other params + # {"by": 'string_missing'}, {"by": ["int", "string"]}, ], )