Skip to content

Commit b25fb5b

Browse files
Require boolean terminal-status callbacks in polling helpers
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 3fbe68e commit b25fb5b

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

hyperbrowser/client/polling.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ def _validate_operation_name(operation_name: str) -> None:
4646
raise HyperbrowserError("operation_name must not contain control characters")
4747

4848

49+
def _ensure_boolean_terminal_result(result: object, *, operation_name: str) -> bool:
50+
if not isinstance(result, bool):
51+
raise HyperbrowserError(
52+
f"is_terminal_status must return a boolean for {operation_name}"
53+
)
54+
return result
55+
56+
4957
def _validate_retry_config(
5058
*,
5159
max_attempts: int,
@@ -154,7 +162,9 @@ def poll_until_terminal_status(
154162
time.sleep(poll_interval_seconds)
155163
continue
156164

157-
if is_terminal_status(status):
165+
if _ensure_boolean_terminal_result(
166+
is_terminal_status(status), operation_name=operation_name
167+
):
158168
return status
159169
if has_exceeded_max_wait(start_time, max_wait_seconds):
160170
raise HyperbrowserTimeoutError(
@@ -225,7 +235,9 @@ async def poll_until_terminal_status_async(
225235
await asyncio.sleep(poll_interval_seconds)
226236
continue
227237

228-
if is_terminal_status(status):
238+
if _ensure_boolean_terminal_result(
239+
is_terminal_status(status), operation_name=operation_name
240+
):
229241
return status
230242
if has_exceeded_max_wait(start_time, max_wait_seconds):
231243
raise HyperbrowserTimeoutError(

tests/test_polling.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,17 @@ def test_polling_helpers_validate_retry_and_interval_configuration():
762762
max_wait_seconds=1.0,
763763
)
764764

765+
with pytest.raises(
766+
HyperbrowserError, match="is_terminal_status must return a boolean"
767+
):
768+
poll_until_terminal_status(
769+
operation_name="invalid-terminal-callback",
770+
get_status=lambda: "completed",
771+
is_terminal_status=lambda value: "yes", # type: ignore[return-value]
772+
poll_interval_seconds=0.0,
773+
max_wait_seconds=1.0,
774+
)
775+
765776
with pytest.raises(
766777
HyperbrowserError, match="max_wait_seconds must be non-negative"
767778
):
@@ -857,6 +868,16 @@ async def validate_async_operation_name() -> None:
857868
poll_interval_seconds=0.1,
858869
max_wait_seconds=1.0,
859870
)
871+
with pytest.raises(
872+
HyperbrowserError, match="is_terminal_status must return a boolean"
873+
):
874+
await poll_until_terminal_status_async(
875+
operation_name="invalid-terminal-callback-async",
876+
get_status=lambda: asyncio.sleep(0, result="completed"),
877+
is_terminal_status=lambda value: "yes", # type: ignore[return-value]
878+
poll_interval_seconds=0.0,
879+
max_wait_seconds=1.0,
880+
)
860881
with pytest.raises(
861882
HyperbrowserError, match="operation_name must be 200 characters or fewer"
862883
):

0 commit comments

Comments
 (0)