From f27fcffe2c4d97cffc7b0c35a40498da53be0a71 Mon Sep 17 00:00:00 2001 From: Marcel Wilson Date: Thu, 21 Sep 2023 14:30:53 -0500 Subject: [PATCH] Allowing user to turn on UNABRIDGED_NARRATION to see why the first action tried failed. --- docs/cookbook.rst | 13 +++++++++++++ screenpy/actions/either.py | 23 +++++++---------------- tests/test_actions.py | 20 +++++++++++++++++++- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/docs/cookbook.rst b/docs/cookbook.rst index f6ec13a..0c8e1bb 100644 --- a/docs/cookbook.rst +++ b/docs/cookbook.rst @@ -290,6 +290,16 @@ passed into :meth:`~screenpy.actions.Either.or_`. Note the Actor only catches ``AssertionError`` here allowing for other exceptions to still be raised. +Other exceptions can be caught when specified. + +.. code-block:: python + + the_actor.will( + Either(DoAction()) + .or_(DoDifferentAction()) + .ignoring(ValueError, AssertionError) + ) + :class:`~screenpy.actions.Either` allows users to pass in multiple actions. This is similar Actor performing multiple actions in one call. @@ -307,6 +317,9 @@ This is similar Actor performing multiple actions in one call. ) ) +:class:`~screenpy.actions.Either` has the ability to ignore other exceptions. +Y + .. note:: :class:`~screenpy.actions.Either` will not describe any cleanup for the Actor diff --git a/screenpy/actions/either.py b/screenpy/actions/either.py index 32d6110..4134045 100644 --- a/screenpy/actions/either.py +++ b/screenpy/actions/either.py @@ -6,6 +6,7 @@ from typing import TYPE_CHECKING +from screenpy.configuration import settings from screenpy.pacing import the_narrator from screenpy.speech_tools import get_additive_description @@ -39,27 +40,17 @@ class Either: def perform_as(self, the_actor: Actor) -> None: """Direct the Actor to do one of two actions using try/accept.""" - # logs the first attempt even if it fails - # try: - # with the_narrator.mic_cable_kinked(): - # the_actor.will(*self.try_performables) - # except AssertionError: - # try: - # the_actor.will(*self.except_performables) - # except Exception as exc: - # raise exc from None - - # Since we are fully expecting assertion error to be raised we kink the - # cable to avoid the explanation; which only happens when the cable is not - # kinked - - # logs the first attempt only if it succeeds. + # kinking the cable before the attempt + # avoids explaning what the actor tries to do. + # logs the first attempt only if it succeeds + # or if UNABRIDGED_NARRATION is enabled with the_narrator.mic_cable_kinked(): try: the_actor.will(*self.try_performables) return except self.ignore_exceptions: - the_narrator.clear_backup() + if not settings.UNABRIDGED_NARRATION: + the_narrator.clear_backup() the_actor.will(*self.except_performables) return diff --git a/tests/test_actions.py b/tests/test_actions.py index 8d171c5..d6871c3 100644 --- a/tests/test_actions.py +++ b/tests/test_actions.py @@ -34,7 +34,7 @@ beat, noted_under, settings, - the_narrator, + the_narrator, aside, ) from screenpy.actions.silently import ( SilentlyAnswerable, @@ -1085,6 +1085,24 @@ def perform_as(self, actor: Actor): assert caplog.records[0].message == "Tester tries to FakeActionPass" + def test_output_first_fails_unabridged(self, Tester, caplog): + class FakeActionFail(Performable): + @beat("{} tries to FakeActionFail") + def perform_as(self, actor: Actor): + raise AssertionError("This Fails!") + + class FakeActionPass(Performable): + @beat("{} tries to FakeActionPass") + def perform_as(self, actor: Actor): + return + + settings.UNABRIDGED_NARRATION = True + with caplog.at_level(logging.INFO): + Either(FakeActionFail()).or_(FakeActionPass()).perform_as(Tester) + settings.UNABRIDGED_NARRATION = False + + assert caplog.records[0].message == "Tester tries to FakeActionFail" + def test_output_first_passes(self, Tester, caplog): class FakeActionFail(Performable): @beat("{} tries to FakeActionFail")