From 72c18fcb3f76289cce5d5d72d3dd267a90cff089 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Thu, 7 Apr 2022 16:16:07 -0700 Subject: [PATCH 1/4] TST: Remove unnecessary setup_method --- pandas/tests/frame/test_query_eval.py | 19 ++-- pandas/tests/indexes/datetimes/test_setops.py | 36 +++--- pandas/tests/internals/test_internals.py | 47 ++++---- pandas/tests/io/test_sql.py | 2 +- pandas/tests/reshape/test_crosstab.py | 107 +++++++++--------- 5 files changed, 102 insertions(+), 109 deletions(-) diff --git a/pandas/tests/frame/test_query_eval.py b/pandas/tests/frame/test_query_eval.py index 266b0e78e885e..65585735d66fd 100644 --- a/pandas/tests/frame/test_query_eval.py +++ b/pandas/tests/frame/test_query_eval.py @@ -1094,20 +1094,19 @@ def test_query_string_scalar_variable(self, parser, engine): class TestDataFrameEvalWithFrame: - def setup_method(self): - self.frame = DataFrame(np.random.randn(10, 3), columns=list("abc")) - def teardown_method(self): - del self.frame + @pytest.fixture + def frame(self): + return DataFrame(np.random.randn(10, 3), columns=list("abc")) - def test_simple_expr(self, parser, engine): - res = self.frame.eval("a + b", engine=engine, parser=parser) - expect = self.frame.a + self.frame.b + def test_simple_expr(self, frame, parser, engine): + res = frame.eval("a + b", engine=engine, parser=parser) + expect = frame.a + frame.b tm.assert_series_equal(res, expect) - def test_bool_arith_expr(self, parser, engine): - res = self.frame.eval("a[a < 1] + b", engine=engine, parser=parser) - expect = self.frame.a[self.frame.a < 1] + self.frame.b + def test_bool_arith_expr(self, frame, parser, engine): + res = frame.eval("a[a < 1] + b", engine=engine, parser=parser) + expect = frame.a[frame.a < 1] + frame.b tm.assert_series_equal(res, expect) @pytest.mark.parametrize("op", ["+", "-", "*", "/"]) diff --git a/pandas/tests/indexes/datetimes/test_setops.py b/pandas/tests/indexes/datetimes/test_setops.py index 4558fcccbb0e1..a0d146f70a2a8 100644 --- a/pandas/tests/indexes/datetimes/test_setops.py +++ b/pandas/tests/indexes/datetimes/test_setops.py @@ -417,27 +417,25 @@ def test_intersection_non_tick_no_fastpath(self): class TestBusinessDatetimeIndex: - def setup_method(self): - self.rng = bdate_range(START, END) - def test_union(self, sort): + rng = date_range(START, END) # overlapping - left = self.rng[:10] - right = self.rng[5:10] + left = rng[:10] + right = rng[5:10] the_union = left.union(right, sort=sort) assert isinstance(the_union, DatetimeIndex) # non-overlapping, gap in middle - left = self.rng[:5] - right = self.rng[10:] + left = rng[:5] + right = rng[10:] the_union = left.union(right, sort=sort) assert isinstance(the_union, Index) # non-overlapping, no gap - left = self.rng[:5] - right = self.rng[5:10] + left = rng[:5] + right = rng[5:10] the_union = left.union(right, sort=sort) assert isinstance(the_union, DatetimeIndex) @@ -452,7 +450,7 @@ def test_union(self, sort): # overlapping, but different offset rng = date_range(START, END, freq=BMonthEnd()) - the_union = self.rng.union(rng, sort=sort) + the_union = rng.union(rng, sort=sort) assert isinstance(the_union, DatetimeIndex) def test_union_not_cacheable(self, sort): @@ -555,27 +553,25 @@ def test_intersection_duplicates(self, sort): class TestCustomDatetimeIndex: - def setup_method(self): - self.rng = bdate_range(START, END, freq="C") - def test_union(self, sort): # overlapping - left = self.rng[:10] - right = self.rng[5:10] + rng = bdate_range(START, END, freq="C") + left = rng[:10] + right = rng[5:10] the_union = left.union(right, sort=sort) assert isinstance(the_union, DatetimeIndex) # non-overlapping, gap in middle - left = self.rng[:5] - right = self.rng[10:] + left = rng[:5] + right = rng[10:] the_union = left.union(right, sort) assert isinstance(the_union, Index) # non-overlapping, no gap - left = self.rng[:5] - right = self.rng[5:10] + left = rng[:5] + right = rng[5:10] the_union = left.union(right, sort=sort) assert isinstance(the_union, DatetimeIndex) @@ -587,7 +583,7 @@ def test_union(self, sort): # overlapping, but different offset rng = date_range(START, END, freq=BMonthEnd()) - the_union = self.rng.union(rng, sort=sort) + the_union = rng.union(rng, sort=sort) assert isinstance(the_union, DatetimeIndex) def test_intersection_bug(self): diff --git a/pandas/tests/internals/test_internals.py b/pandas/tests/internals/test_internals.py index f4060c84f533a..3c90eee5be999 100644 --- a/pandas/tests/internals/test_internals.py +++ b/pandas/tests/internals/test_internals.py @@ -243,13 +243,12 @@ def create_mgr(descr, item_shape=None): ) -class TestBlock: - def setup_method(self): - self.fblock = create_block("float", [0, 2, 4]) - self.cblock = create_block("complex", [7]) - self.oblock = create_block("object", [1, 3]) - self.bool_block = create_block("bool", [5]) +@pytest.fixture +def fblock(): + return create_block("float", [0, 2, 4]) + +class TestBlock: def test_constructor(self): int32block = create_block("i4", [0]) assert int32block.dtype == np.int32 @@ -267,24 +266,24 @@ def test_pickle(self, typ, data): blk = create_block(typ, data) assert_block_equal(tm.round_trip_pickle(blk), blk) - def test_mgr_locs(self): - assert isinstance(self.fblock.mgr_locs, BlockPlacement) + def test_mgr_locs(self, fblock): + assert isinstance(fblock.mgr_locs, BlockPlacement) tm.assert_numpy_array_equal( - self.fblock.mgr_locs.as_array, np.array([0, 2, 4], dtype=np.intp) + fblock.mgr_locs.as_array, np.array([0, 2, 4], dtype=np.intp) ) - def test_attrs(self): - assert self.fblock.shape == self.fblock.values.shape - assert self.fblock.dtype == self.fblock.values.dtype - assert len(self.fblock) == len(self.fblock.values) + def test_attrs(self, fblock): + assert fblock.shape == fblock.values.shape + assert fblock.dtype == fblock.values.dtype + assert len(fblock) == len(fblock.values) - def test_copy(self): - cop = self.fblock.copy() - assert cop is not self.fblock - assert_block_equal(self.fblock, cop) + def test_copy(self, fblock): + cop = fblock.copy() + assert cop is not fblock + assert_block_equal(fblock, cop) - def test_delete(self): - newb = self.fblock.copy() + def test_delete(self, fblock): + newb = fblock.copy() locs = newb.mgr_locs nb = newb.delete(0) assert newb.mgr_locs is locs @@ -297,7 +296,7 @@ def test_delete(self): assert not (newb.values[0] == 1).all() assert (nb.values[0] == 1).all() - newb = self.fblock.copy() + newb = fblock.copy() locs = newb.mgr_locs nb = newb.delete(1) assert newb.mgr_locs is locs @@ -308,7 +307,7 @@ def test_delete(self): assert not (newb.values[1] == 2).all() assert (nb.values[1] == 2).all() - newb = self.fblock.copy() + newb = fblock.copy() locs = newb.mgr_locs nb = newb.delete(2) tm.assert_numpy_array_equal( @@ -316,7 +315,7 @@ def test_delete(self): ) assert (nb.values[1] == 1).all() - newb = self.fblock.copy() + newb = fblock.copy() with pytest.raises(IndexError, match=None): newb.delete(3) @@ -357,9 +356,9 @@ def test_split(self): for res, exp in zip(result, expected): assert_block_equal(res, exp) - def test_is_categorical_deprecated(self): + def test_is_categorical_deprecated(self, fblock): # GH#40571 - blk = self.fblock + blk = fblock with tm.assert_produces_warning(DeprecationWarning): blk.is_categorical diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index e4318f1d79102..e28901fa1a1ed 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -650,7 +650,7 @@ def psql_insert_copy(table, conn, keys, data_iter): class MixInBase: - def teardown_method(self, method): + def teardown_method(self): # if setup fails, there may not be a connection to close. if hasattr(self, "conn"): for tbl in self._get_all_tables(): diff --git a/pandas/tests/reshape/test_crosstab.py b/pandas/tests/reshape/test_crosstab.py index 65b126c0fd98f..76448d5942a5a 100644 --- a/pandas/tests/reshape/test_crosstab.py +++ b/pandas/tests/reshape/test_crosstab.py @@ -15,66 +15,65 @@ import pandas._testing as tm -class TestCrosstab: - def setup_method(self): - df = DataFrame( - { - "A": [ - "foo", - "foo", - "foo", - "foo", - "bar", - "bar", - "bar", - "bar", - "foo", - "foo", - "foo", - ], - "B": [ - "one", - "one", - "one", - "two", - "one", - "one", - "one", - "two", - "two", - "two", - "one", - ], - "C": [ - "dull", - "dull", - "shiny", - "dull", - "dull", - "shiny", - "shiny", - "dull", - "shiny", - "shiny", - "shiny", - ], - "D": np.random.randn(11), - "E": np.random.randn(11), - "F": np.random.randn(11), - } - ) +@pytest.fixture +def df(): + df = DataFrame( + { + "A": [ + "foo", + "foo", + "foo", + "foo", + "bar", + "bar", + "bar", + "bar", + "foo", + "foo", + "foo", + ], + "B": [ + "one", + "one", + "one", + "two", + "one", + "one", + "one", + "two", + "two", + "two", + "one", + ], + "C": [ + "dull", + "dull", + "shiny", + "dull", + "dull", + "shiny", + "shiny", + "dull", + "shiny", + "shiny", + "shiny", + ], + "D": np.random.randn(11), + "E": np.random.randn(11), + "F": np.random.randn(11), + } + ) - self.df = pd.concat([df, df], ignore_index=True) + return pd.concat([df, df], ignore_index=True) - def test_crosstab_single(self): - df = self.df + +class TestCrosstab: + def test_crosstab_single(self, df): result = crosstab(df["A"], df["C"]) expected = df.groupby(["A", "C"]).size().unstack() tm.assert_frame_equal(result, expected.fillna(0).astype(np.int64)) - def test_crosstab_multiple(self): - df = self.df - + def test_crosstab_multiple(self, df): result = crosstab(df["A"], [df["B"], df["C"]]) expected = df.groupby(["A", "B", "C"]).size() expected = expected.unstack("B").unstack("C").fillna(0).astype(np.int64) From e518233ad0331b83cd923755615be9efd14f1e85 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Thu, 7 Apr 2022 17:10:04 -0700 Subject: [PATCH 2/4] Refactor more setup_method --- pandas/tests/indexing/test_categorical.py | 58 +++--- pandas/tests/io/formats/style/test_style.py | 180 ++++++++-------- pandas/tests/io/formats/test_format.py | 18 +- .../json/test_json_table_schema_ext_dtype.py | 22 +- pandas/tests/plotting/test_converter.py | 74 +++---- pandas/tests/reshape/merge/test_join.py | 2 - .../tests/reshape/merge/test_merge_ordered.py | 37 ++-- pandas/tests/reshape/test_melt.py | 196 ++++++++++-------- 8 files changed, 301 insertions(+), 286 deletions(-) diff --git a/pandas/tests/indexing/test_categorical.py b/pandas/tests/indexing/test_categorical.py index eb38edd920082..ab1c8ece38cc0 100644 --- a/pandas/tests/indexing/test_categorical.py +++ b/pandas/tests/indexing/test_categorical.py @@ -20,32 +20,37 @@ from pandas.api.types import CategoricalDtype as CDT -class TestCategoricalIndex: - def setup_method(self): - - self.df = DataFrame( +@pytest.fixture +def df(): + return DataFrame( { "A": np.arange(6, dtype="int64"), }, index=CategoricalIndex(list("aabbca"), dtype=CDT(list("cab")), name="B"), ) - self.df2 = DataFrame( + + +@pytest.fixture +def df2(): + return DataFrame( { "A": np.arange(6, dtype="int64"), }, index=CategoricalIndex(list("aabbca"), dtype=CDT(list("cabe")), name="B"), ) - def test_loc_scalar(self): + +class TestCategoricalIndex: + def test_loc_scalar(self, df): dtype = CDT(list("cab")) - result = self.df.loc["a"] + result = df.loc["a"] bidx = Series(list("aaa"), name="B").astype(dtype) assert bidx.dtype == dtype expected = DataFrame({"A": [0, 1, 5]}, index=Index(bidx)) tm.assert_frame_equal(result, expected) - df = self.df.copy() + df = df.copy() df.loc["a"] = 20 bidx2 = Series(list("aabbca"), name="B").astype(dtype) assert bidx2.dtype == dtype @@ -68,9 +73,8 @@ def test_loc_scalar(self): df2.loc["d"] = 10 tm.assert_frame_equal(df2, expected) - def test_loc_setitem_with_expansion_non_category(self): + def test_loc_setitem_with_expansion_non_category(self, df): # Setting-with-expansion with a new key "d" that is not among caegories - df = self.df df.loc["a"] = 20 # Setting a new row on an existing column @@ -97,9 +101,9 @@ def test_loc_setitem_with_expansion_non_category(self): ) tm.assert_frame_equal(df4, expected3) - def test_loc_getitem_scalar_non_category(self): + def test_loc_getitem_scalar_non_category(self, df): with pytest.raises(KeyError, match="^1$"): - self.df.loc[1] + df.loc[1] def test_slicing(self): cat = Series(Categorical([1, 2, 3, 4])) @@ -287,31 +291,31 @@ def test_slicing_doc_examples(self): ) tm.assert_frame_equal(result, expected) - def test_loc_getitem_listlike_labels(self): + def test_loc_getitem_listlike_labels(self, df): # list of labels - result = self.df.loc[["c", "a"]] - expected = self.df.iloc[[4, 0, 1, 5]] + result = df.loc[["c", "a"]] + expected = df.iloc[[4, 0, 1, 5]] tm.assert_frame_equal(result, expected, check_index_type=True) - def test_loc_getitem_listlike_unused_category(self): + def test_loc_getitem_listlike_unused_category(self, df2): # GH#37901 a label that is in index.categories but not in index # listlike containing an element in the categories but not in the values with pytest.raises(KeyError, match=re.escape("['e'] not in index")): - self.df2.loc[["a", "b", "e"]] + df2.loc[["a", "b", "e"]] - def test_loc_getitem_label_unused_category(self): + def test_loc_getitem_label_unused_category(self, df2): # element in the categories but not in the values with pytest.raises(KeyError, match=r"^'e'$"): - self.df2.loc["e"] + df2.loc["e"] - def test_loc_getitem_non_category(self): + def test_loc_getitem_non_category(self, df2): # not all labels in the categories with pytest.raises(KeyError, match=re.escape("['d'] not in index")): - self.df2.loc[["a", "d"]] + df2.loc[["a", "d"]] - def test_loc_setitem_expansion_label_unused_category(self): + def test_loc_setitem_expansion_label_unused_category(self, df2): # assigning with a label that is in the categories but not in the index - df = self.df2.copy() + df = df2.copy() df.loc["e"] = 20 result = df.loc[["a", "b", "e"]] exp_index = CategoricalIndex(list("aaabbe"), categories=list("cabe"), name="B") @@ -450,17 +454,17 @@ def test_ix_categorical_index_non_unique(self): ) tm.assert_frame_equal(cdf.loc[:, ["X", "Y"]], expect) - def test_loc_slice(self): + def test_loc_slice(self, df): # GH9748 msg = ( "cannot do slice indexing on CategoricalIndex with these " r"indexers \[1\] of type int" ) with pytest.raises(TypeError, match=msg): - self.df.loc[1:5] + df.loc[1:5] - result = self.df.loc["b":"c"] - expected = self.df.iloc[[2, 3, 4]] + result = df.loc["b":"c"] + expected = df.iloc[[2, 3, 4]] tm.assert_frame_equal(result, expected) def test_loc_and_at_with_categorical_index(self): diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 62608e2f17267..8387ab5076eea 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -80,6 +80,25 @@ def mi_styler_comp(mi_styler): return mi_styler +@pytest.fixture +def blank_value(): + return " " + + +@pytest.fixture +def df(): + np.random.seed(24) + df = DataFrame({"A": [0, 1], "B": np.random.randn(2)}) + return df + + +@pytest.fixture +def styler(df): + np.random.seed(24) + df = DataFrame({"A": [0, 1], "B": np.random.randn(2)}) + return Styler(df) + + @pytest.mark.parametrize( "sparse_columns, exp_cols", [ @@ -444,25 +463,6 @@ def test_apply_map_header_raises(mi_styler): class TestStyler: - def setup_method(self): - np.random.seed(24) - self.s = DataFrame({"A": np.random.permutation(range(6))}) - self.df = DataFrame({"A": [0, 1], "B": np.random.randn(2)}) - self.f = lambda x: x - self.g = lambda x: x - - def h(x, foo="bar"): - return Series(f"color: {foo}", index=x.index, name=x.name) - - self.h = h - self.styler = Styler(self.df) - self.attrs = DataFrame({"A": ["color: red", "color: blue"]}) - self.dataframes = [ - self.df, - DataFrame({"f": [1.0, 2.0], "o": ["a", "b"], "c": Categorical(["a", "b"])}), - ] - self.blank_value = " " - def test_init_non_pandas(self): msg = "``data`` must be a Series or DataFrame" with pytest.raises(TypeError, match=msg): @@ -472,29 +472,29 @@ def test_init_series(self): result = Styler(Series([1, 2])) assert result.data.ndim == 2 - def test_repr_html_ok(self): - self.styler._repr_html_() + def test_repr_html_ok(self, styler): + styler._repr_html_() - def test_repr_html_mathjax(self): + def test_repr_html_mathjax(self, styler): # gh-19824 / 41395 - assert "tex2jax_ignore" not in self.styler._repr_html_() + assert "tex2jax_ignore" not in styler._repr_html_() with option_context("styler.html.mathjax", False): - assert "tex2jax_ignore" in self.styler._repr_html_() + assert "tex2jax_ignore" in styler._repr_html_() - def test_update_ctx(self): - self.styler._update_ctx(self.attrs) + def test_update_ctx(self, styler): + styler._update_ctx(DataFrame({"A": ["color: red", "color: blue"]})) expected = {(0, 0): [("color", "red")], (1, 0): [("color", "blue")]} - assert self.styler.ctx == expected + assert styler.ctx == expected - def test_update_ctx_flatten_multi_and_trailing_semi(self): + def test_update_ctx_flatten_multi_and_trailing_semi(self, styler): attrs = DataFrame({"A": ["color: red; foo: bar", "color:blue ; foo: baz;"]}) - self.styler._update_ctx(attrs) + styler._update_ctx(attrs) expected = { (0, 0): [("color", "red"), ("foo", "bar")], (1, 0): [("color", "blue"), ("foo", "baz")], } - assert self.styler.ctx == expected + assert styler.ctx == expected def test_render(self): df = DataFrame({"A": [0, 1]}) @@ -503,9 +503,9 @@ def test_render(self): s.to_html() # it worked? - def test_multiple_render(self): + def test_multiple_render(self, df): # GH 39396 - s = Styler(self.df, uuid_len=0).applymap(lambda x: "color: red;", subset=["A"]) + s = Styler(df, uuid_len=0).applymap(lambda x: "color: red;", subset=["A"]) s.to_html() # do 2 renders to ensure css styles not duplicated assert ( '