Skip to content

Commit 615ea3a

Browse files
Validate polling helper numeric input types
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 8deb73a commit 615ea3a

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

hyperbrowser/client/polling.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
from numbers import Real
23
import time
34
from typing import Awaitable, Callable, Optional, TypeVar
45

@@ -17,20 +18,39 @@ def _validate_retry_config(
1718
retry_delay_seconds: float,
1819
max_status_failures: Optional[int] = None,
1920
) -> None:
21+
if isinstance(max_attempts, bool) or not isinstance(max_attempts, int):
22+
raise HyperbrowserError("max_attempts must be an integer")
2023
if max_attempts < 1:
2124
raise HyperbrowserError("max_attempts must be at least 1")
25+
if isinstance(retry_delay_seconds, bool) or not isinstance(
26+
retry_delay_seconds, Real
27+
):
28+
raise HyperbrowserError("retry_delay_seconds must be a number")
2229
if retry_delay_seconds < 0:
2330
raise HyperbrowserError("retry_delay_seconds must be non-negative")
24-
if max_status_failures is not None and max_status_failures < 1:
25-
raise HyperbrowserError("max_status_failures must be at least 1")
31+
if max_status_failures is not None:
32+
if isinstance(max_status_failures, bool) or not isinstance(
33+
max_status_failures, int
34+
):
35+
raise HyperbrowserError("max_status_failures must be an integer")
36+
if max_status_failures < 1:
37+
raise HyperbrowserError("max_status_failures must be at least 1")
2638

2739

2840
def _validate_poll_interval(poll_interval_seconds: float) -> None:
41+
if isinstance(poll_interval_seconds, bool) or not isinstance(
42+
poll_interval_seconds, Real
43+
):
44+
raise HyperbrowserError("poll_interval_seconds must be a number")
2945
if poll_interval_seconds < 0:
3046
raise HyperbrowserError("poll_interval_seconds must be non-negative")
3147

3248

3349
def _validate_max_wait_seconds(max_wait_seconds: Optional[float]) -> None:
50+
if max_wait_seconds is not None and (
51+
isinstance(max_wait_seconds, bool) or not isinstance(max_wait_seconds, Real)
52+
):
53+
raise HyperbrowserError("max_wait_seconds must be a number")
3454
if max_wait_seconds is not None and max_wait_seconds < 0:
3555
raise HyperbrowserError("max_wait_seconds must be non-negative")
3656

tests/test_polling.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,14 @@ def test_polling_helpers_validate_retry_and_interval_configuration():
394394
retry_delay_seconds=0,
395395
)
396396

397+
with pytest.raises(HyperbrowserError, match="max_attempts must be an integer"):
398+
retry_operation(
399+
operation_name="invalid-retry-type",
400+
operation=lambda: "ok",
401+
max_attempts=1.5, # type: ignore[arg-type]
402+
retry_delay_seconds=0,
403+
)
404+
397405
with pytest.raises(
398406
HyperbrowserError, match="retry_delay_seconds must be non-negative"
399407
):
@@ -416,6 +424,18 @@ def test_polling_helpers_validate_retry_and_interval_configuration():
416424
max_status_failures=0,
417425
)
418426

427+
with pytest.raises(
428+
HyperbrowserError, match="max_status_failures must be an integer"
429+
):
430+
poll_until_terminal_status(
431+
operation_name="invalid-status-failures-type",
432+
get_status=lambda: "completed",
433+
is_terminal_status=lambda value: value == "completed",
434+
poll_interval_seconds=0.1,
435+
max_wait_seconds=1.0,
436+
max_status_failures=1.5, # type: ignore[arg-type]
437+
)
438+
419439
with pytest.raises(
420440
HyperbrowserError, match="poll_interval_seconds must be non-negative"
421441
):
@@ -427,6 +447,17 @@ def test_polling_helpers_validate_retry_and_interval_configuration():
427447
max_wait_seconds=1.0,
428448
)
429449

450+
with pytest.raises(
451+
HyperbrowserError, match="poll_interval_seconds must be a number"
452+
):
453+
poll_until_terminal_status(
454+
operation_name="invalid-poll-interval-type",
455+
get_status=lambda: "completed",
456+
is_terminal_status=lambda value: value == "completed",
457+
poll_interval_seconds="0.1", # type: ignore[arg-type]
458+
max_wait_seconds=1.0,
459+
)
460+
430461
with pytest.raises(
431462
HyperbrowserError, match="max_wait_seconds must be non-negative"
432463
):
@@ -440,3 +471,15 @@ def test_polling_helpers_validate_retry_and_interval_configuration():
440471
max_attempts=1,
441472
retry_delay_seconds=0.0,
442473
)
474+
475+
with pytest.raises(HyperbrowserError, match="max_wait_seconds must be a number"):
476+
collect_paginated_results(
477+
operation_name="invalid-max-wait-type",
478+
get_next_page=lambda page: {"current": 1, "total": 1, "items": []},
479+
get_current_page_batch=lambda response: response["current"],
480+
get_total_page_batches=lambda response: response["total"],
481+
on_page_success=lambda response: None,
482+
max_wait_seconds="1", # type: ignore[arg-type]
483+
max_attempts=1,
484+
retry_delay_seconds=0.0,
485+
)

0 commit comments

Comments
 (0)