From e70bf99a89f27102247613bcd5d1aa8923a1cda9 Mon Sep 17 00:00:00 2001 From: "typesafe-public-bot[bot]" <321128928+typesafe-public-bot[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 15:46:17 +0000 Subject: [PATCH] Release v0.7.4 Co-authored-by: Daniel Gafni --- docs/changelog.md | 6 ++++++ pyproject.toml | 2 +- src/typesafe_sdk/_core/json.py | 3 ++- tests/test_clients.py | 15 +++++++++++++++ uv.lock | 2 +- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 9c83a8d..c78e9bd 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -5,6 +5,12 @@ icon: lucide/history # Changelog +## v0.7.4 (2026-10-09) + +### Bug fixes + +- serialize non-finite numbers as strings instead of invalid JSON tokens + ## v0.7.3 (2026-10-09) ### Bug fixes diff --git a/pyproject.toml b/pyproject.toml index a7b8a0c..6063588 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "typesafe-sdk" -version = "0.7.3" +version = "0.7.4" description = "Python SDK for TypeSafe AI API." readme = "README.md" license = "MIT" diff --git a/src/typesafe_sdk/_core/json.py b/src/typesafe_sdk/_core/json.py index 29337b0..78c1eab 100644 --- a/src/typesafe_sdk/_core/json.py +++ b/src/typesafe_sdk/_core/json.py @@ -23,7 +23,8 @@ def _fallback(value: object) -> object: def serialize(value: object) -> bytes: - return to_json(value, fallback=_fallback) + # JSON has no NaN/Infinity tokens; emit them as the strings "NaN"/"Infinity"/"-Infinity" instead. + return to_json(value, fallback=_fallback, inf_nan_mode="strings") def deserialize(content: bytes) -> Any: diff --git a/tests/test_clients.py b/tests/test_clients.py index d96f0f2..f0fe3ca 100644 --- a/tests/test_clients.py +++ b/tests/test_clients.py @@ -161,6 +161,21 @@ async def test_unserializable_request_body_raises(clients: ClientFactory) -> Non ) +async def test_non_finite_numbers_are_stringified(clients: ClientFactory) -> None: + def handler(request: httpx2.Request) -> httpx2.Response: + body = from_json(request.content, allow_inf_nan=False) + assert body["state"] == {"value": "NaN", "arr": [1.0, "Infinity", "-Infinity"]} + assert body["temperature"] == "NaN" + return httpx2.Response(200, content=to_json(RESULT)) + + await system_one( + clients(handler), + state={"value": float("nan"), "arr": [1.0, float("inf"), float("-inf")]}, + questions={"q": {"type": "noul", "instructions": "?"}}, + extra_body={"temperature": float("nan")}, + ) + + async def test_raw_question_passthrough(clients: ClientFactory) -> None: # Explicit escape hatch for fields introduced by the API before this SDK models them. questions = cast( diff --git a/uv.lock b/uv.lock index a3adad4..76f5bf4 100644 --- a/uv.lock +++ b/uv.lock @@ -1238,7 +1238,7 @@ wheels = [ [[package]] name = "typesafe-sdk" -version = "0.7.3" +version = "0.7.4" source = { editable = "." } dependencies = [ { name = "httpx2" },