From 404f92345868ba6ce4542e0141415635b1d1398a Mon Sep 17 00:00:00 2001 From: Matthew Horoszowski Date: Sun, 22 Mar 2026 09:24:21 -0400 Subject: [PATCH] feature: add Slide.is_hidden read/write property Add the ability to get and set whether a slide is hidden from the presentation. Maps to the `show` attribute on the `` element, where show="0" means the slide is hidden. Co-Authored-By: Claude Opus 4.6 (1M context) --- features/sld-slide.feature | 16 ++++++++++ features/steps/slide.py | 23 +++++++++++++- .../steps/test_files/sld-slide-hidden.pptx | Bin 0 -> 29036 bytes src/pptx/oxml/slide.py | 5 ++- src/pptx/slide.py | 12 +++++++ tests/test_slide.py | 30 ++++++++++++++++++ 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 features/steps/test_files/sld-slide-hidden.pptx diff --git a/features/sld-slide.feature b/features/sld-slide.feature index 1c8f88a88..fc62b22fb 100644 --- a/features/sld-slide.feature +++ b/features/sld-slide.feature @@ -14,6 +14,22 @@ Feature: slide properties | an overridden | + Scenario Outline: Slide.is_hidden + Given a slide having visibility + Then slide.is_hidden is + + Examples: Slide.is_hidden cases + | hidden-or-visible | value | + | visible | False | + | hidden | True | + + + Scenario: Slide.is_hidden setter + Given a slide having visible visibility + When I assign True to slide.is_hidden + Then slide.is_hidden is True + + Scenario Outline: Slide.follow_master_background Given a Slide object having background as slide Then slide.follow_master_background is diff --git a/features/steps/slide.py b/features/steps/slide.py index a7527f36d..bd60f2fcb 100644 --- a/features/steps/slide.py +++ b/features/steps/slide.py @@ -2,7 +2,7 @@ from __future__ import annotations -from behave import given, then +from behave import given, then, when from helpers import test_pptx from pptx import Presentation @@ -28,6 +28,12 @@ def given_a_slide(context): context.slide = presentation.slides[0] +@given("a slide having {visibility} visibility") +def given_a_slide_having_visibility(context, visibility): + slide_idx = {"visible": 0, "hidden": 1}[visibility] + context.slide = Presentation(test_pptx("sld-slide-hidden")).slides[slide_idx] + + @given("a slide having a notes slide") def given_a_slide_having_a_notes_slide(context): context.slide = Presentation(test_pptx("sld-notes")).slides[0] @@ -96,6 +102,14 @@ def given_a_SlideMaster_object_as_slide(context): context.slide = context.slide_master = prs.slide_masters[0] +# when ==================================================== + + +@when("I assign {value} to slide.is_hidden") +def when_I_assign_value_to_slide_is_hidden(context, value): + context.slide.is_hidden = {"True": True, "False": False}[value] + + # then ==================================================== @@ -136,6 +150,13 @@ def then_slide_background_is_a_Background_object(context): assert cls_name == "_Background", "slide.background is a %s object" % cls_name +@then("slide.is_hidden is {value}") +def then_slide_is_hidden_is_value(context, value): + expected_value = {"True": True, "False": False}[value] + actual_value = context.slide.is_hidden + assert actual_value is expected_value, "slide.is_hidden is %s" % actual_value + + @then("slide.follow_master_background is {value}") def then_slide_follow_master_background_is_value(context, value): expected_value = {"True": True, "False": False}[value] diff --git a/features/steps/test_files/sld-slide-hidden.pptx b/features/steps/test_files/sld-slide-hidden.pptx new file mode 100644 index 0000000000000000000000000000000000000000..c4bded969f7b916949e5a7d14f6a4ae358637e9b GIT binary patch literal 29036 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 CT_Slide: diff --git a/src/pptx/slide.py b/src/pptx/slide.py index 3b1b65d8e..864556c24 100644 --- a/src/pptx/slide.py +++ b/src/pptx/slide.py @@ -178,6 +178,18 @@ class Slide(_BaseSlide): part: SlidePart # pyright: ignore[reportIncompatibleMethodOverride] + @property + def is_hidden(self) -> bool: + """`True` if this slide is hidden from the presentation, `False` otherwise. + + Assigning `True` causes the slide to be hidden. Assigning `False` makes the slide visible. + """ + return not self._element.show + + @is_hidden.setter + def is_hidden(self, value: bool) -> None: + self._element.show = not value + @property def follow_master_background(self): """|True| if this slide inherits the slide master background. diff --git a/tests/test_slide.py b/tests/test_slide.py index 74b528c3b..3339c3796 100644 --- a/tests/test_slide.py +++ b/tests/test_slide.py @@ -309,6 +309,36 @@ def it_provides_access_to_its_background(self, background_fixture): _BaseSlide_background_.assert_called_once_with() assert background is background_ + @pytest.mark.parametrize( + ("sld_cxml", "expected_value"), + [ + ("p:sld/p:cSld", False), + ("p:sld{show=1}/p:cSld", False), + ("p:sld{show=0}/p:cSld", True), + ("p:sld{show=false}/p:cSld", True), + ("p:sld{show=true}/p:cSld", False), + ], + ) + def it_knows_whether_it_is_hidden(self, sld_cxml: str, expected_value: bool): + slide = Slide(element(sld_cxml), None) + assert slide.is_hidden is expected_value + + @pytest.mark.parametrize( + ("sld_cxml", "new_value", "expected_cxml"), + [ + ("p:sld/p:cSld", True, "p:sld{show=0}/p:cSld"), + ("p:sld/p:cSld", False, "p:sld/p:cSld"), + ("p:sld{show=0}/p:cSld", False, "p:sld/p:cSld"), + ("p:sld{show=0}/p:cSld", True, "p:sld{show=0}/p:cSld"), + ], + ) + def it_can_change_whether_it_is_hidden( + self, sld_cxml: str, new_value: bool, expected_cxml: str + ): + slide = Slide(element(sld_cxml), None) + slide.is_hidden = new_value + assert slide._element.xml == xml(expected_cxml) + def it_knows_whether_it_follows_the_mstr_bkgd(self, follow_get_fixture): slide, expected_value = follow_get_fixture follows = slide.follow_master_background