Skip to content

Commit 105965b

Browse files
Normalize client timeout values to float before transport assignment
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 6b2b57d commit 105965b

4 files changed

Lines changed: 38 additions & 6 deletions

File tree

hyperbrowser/client/async_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def __init__(
2727
headers: Optional[Mapping[str, str]] = None,
2828
timeout: Optional[float] = 30,
2929
):
30-
validate_timeout_seconds(timeout)
30+
timeout = validate_timeout_seconds(timeout)
3131
super().__init__(AsyncTransport, config, api_key, base_url, headers)
3232
self.transport.client.timeout = timeout
3333
self.sessions = SessionManager(self)

hyperbrowser/client/sync.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def __init__(
2727
headers: Optional[Mapping[str, str]] = None,
2828
timeout: Optional[float] = 30,
2929
):
30-
validate_timeout_seconds(timeout)
30+
timeout = validate_timeout_seconds(timeout)
3131
super().__init__(SyncTransport, config, api_key, base_url, headers)
3232
self.transport.client.timeout = timeout
3333
self.sessions = SessionManager(self)

hyperbrowser/client/timeout_utils.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@
55
from ..exceptions import HyperbrowserError
66

77

8-
def validate_timeout_seconds(timeout: Optional[float]) -> None:
8+
def validate_timeout_seconds(timeout: Optional[float]) -> Optional[float]:
99
if timeout is None:
10-
return
10+
return None
1111
if isinstance(timeout, bool) or not isinstance(timeout, Real):
1212
raise HyperbrowserError("timeout must be a number")
1313
try:
14-
is_finite = math.isfinite(timeout)
14+
normalized_timeout = float(timeout)
15+
except (TypeError, ValueError, OverflowError) as exc:
16+
raise HyperbrowserError("timeout must be finite") from exc
17+
try:
18+
is_finite = math.isfinite(normalized_timeout)
1519
except (TypeError, ValueError, OverflowError):
1620
is_finite = False
1721
if not is_finite:
1822
raise HyperbrowserError("timeout must be finite")
19-
if timeout < 0:
23+
if normalized_timeout < 0:
2024
raise HyperbrowserError("timeout must be non-negative")
25+
return normalized_timeout

tests/test_client_timeout.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,33 @@ async def run() -> None:
3131
asyncio.run(run())
3232

3333

34+
def test_sync_client_normalizes_fraction_timeout_to_float():
35+
client = Hyperbrowser(
36+
api_key="test-key",
37+
timeout=Fraction(1, 2), # type: ignore[arg-type]
38+
)
39+
try:
40+
assert isinstance(client.transport.client.timeout.connect, float)
41+
assert client.transport.client.timeout.connect == 0.5
42+
finally:
43+
client.close()
44+
45+
46+
def test_async_client_normalizes_fraction_timeout_to_float():
47+
async def run() -> None:
48+
client = AsyncHyperbrowser(
49+
api_key="test-key",
50+
timeout=Fraction(1, 2), # type: ignore[arg-type]
51+
)
52+
try:
53+
assert isinstance(client.transport.client.timeout.connect, float)
54+
assert client.transport.client.timeout.connect == 0.5
55+
finally:
56+
await client.close()
57+
58+
asyncio.run(run())
59+
60+
3461
def test_sync_client_rejects_non_numeric_timeout():
3562
with pytest.raises(HyperbrowserError, match="timeout must be a number"):
3663
Hyperbrowser(api_key="test-key", timeout="30") # type: ignore[arg-type]

0 commit comments

Comments
 (0)