diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index efc8bc695df85..f6e5e8b21327d 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -409,7 +409,7 @@ ExtensionArray Styler ^^^^^^ -- +- Bug in :meth:`Styler._copy` calling overridden methods in subclasses of :class:`Styler` (:issue:`52728`) - Other diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index e2c5ed2ea92b6..f647f13c5cc89 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1578,8 +1578,8 @@ def _copy(self, deepcopy: bool = False) -> Styler: - applied styles (_todo) """ - # GH 40675 - styler = Styler( + # GH 40675, 52728 + styler = type(self)( self.data, # populates attributes 'data', 'columns', 'index' as shallow ) shallow = [ # simple string or boolean immutables diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 0abe4b82e8848..f1eb6ee3c5c62 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -313,6 +313,20 @@ def test_copy(comprehensive, render, deepcopy, mi_styler, mi_styler_comp): assert id(getattr(s2, attr)) != id(getattr(styler, attr)) +@pytest.mark.parametrize("deepcopy", [True, False]) +def test_inherited_copy(mi_styler, deepcopy): + # Ensure that the inherited class is preserved when a Styler object is copied. + # GH 52728 + class CustomStyler(Styler): + pass + + custom_styler = CustomStyler(mi_styler.data) + custom_styler_copy = ( + copy.deepcopy(custom_styler) if deepcopy else copy.copy(custom_styler) + ) + assert isinstance(custom_styler_copy, CustomStyler) + + def test_clear(mi_styler_comp): # NOTE: if this test fails for new features then 'mi_styler_comp' should be updated # to ensure proper testing of the 'copy', 'clear', 'export' methods with new feature