@@ -247,6 +247,17 @@ def test_whole_positive_float_coerced_to_int(self) -> None:
247247 d = AssistantMessageData .model_validate ({"outputTokens" : 100.0 })
248248 assert d .outputTokens == 100
249249
250+ @pytest .mark .parametrize ("raw" , [float ("inf" ), float ("-inf" ), float ("nan" )])
251+ def test_special_float_maps_to_zero (self , raw : float ) -> None :
252+ """IEEE 754 special floats on the Pydantic boundary must map to 0."""
253+ d = AssistantMessageData .model_validate ({"outputTokens" : raw })
254+ assert d .outputTokens == 0
255+
256+ def test_negative_zero_float_maps_to_zero (self ) -> None :
257+ """-0.0 on the Pydantic boundary must map to 0."""
258+ d = AssistantMessageData .model_validate ({"outputTokens" : - 0.0 })
259+ assert d .outputTokens == 0
260+
250261
251262def test_session_shutdown_data () -> None :
252263 d = SessionShutdownData .model_validate (RAW_SHUTDOWN ["data" ])
@@ -407,6 +418,15 @@ def test_zero_or_negative_float_returns_none(self, value: float) -> None:
407418 """Zero and negative whole floats must be rejected."""
408419 assert parse_token_int (value ) is None
409420
421+ @pytest .mark .parametrize ("raw" , [float ("inf" ), float ("-inf" ), float ("nan" )])
422+ def test_special_float_returns_none (self , raw : float ) -> None :
423+ """IEEE 754 special floats must be rejected, not coerced to int."""
424+ assert parse_token_int (raw ) is None
425+
426+ def test_negative_zero_float_returns_none (self ) -> None :
427+ """-0.0 passes is_integer() but must not count as a positive token value."""
428+ assert parse_token_int (- 0.0 ) is None
429+
410430 @pytest .mark .parametrize ("value" , [None , {}, [], object ()])
411431 def test_other_types_return_none (self , value : object ) -> None :
412432 """Unsupported types must be rejected."""
0 commit comments