From 1674c6659d95f3a661f254e6b6f7294fabee6035 Mon Sep 17 00:00:00 2001 From: Patrick Magee Date: Fri, 26 Jul 2024 11:05:33 +0100 Subject: [PATCH 1/2] Fix data loss with 'None' being returned incases where a JSON Parse node that contains a 'number' is not a true 'floating point number' with a 'decimal' but is a integer value, though still defined in the OpenAPI Spec as a number (which allows integers) and could potentially hint to the client if that's generally a float or double. In the case where no hint is provided to the client, I think the same behaviour should happen, a simple conversion from integer to float type in the Kiota side. Signed-off-by: Patrick Magee --- kiota_serialization_json/json_parse_node.py | 4 ++-- tests/unit/test_json_parse_node.py | 22 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/kiota_serialization_json/json_parse_node.py b/kiota_serialization_json/json_parse_node.py index 2a2dd4f..1364f96 100644 --- a/kiota_serialization_json/json_parse_node.py +++ b/kiota_serialization_json/json_parse_node.py @@ -67,9 +67,9 @@ def get_int_value(self) -> Optional[int]: def get_float_value(self) -> Optional[float]: """Gets the float value of the json node Returns: - float: The integer value of the node + float: The number value of the node """ - return self._json_node if isinstance(self._json_node, float) else None + return float(self._json_node) if isinstance(self._json_node, (float, int)) else None def get_uuid_value(self) -> Optional[UUID]: """Gets the UUID value of the json node diff --git a/tests/unit/test_json_parse_node.py b/tests/unit/test_json_parse_node.py index d5c605a..8b6814f 100644 --- a/tests/unit/test_json_parse_node.py +++ b/tests/unit/test_json_parse_node.py @@ -28,12 +28,32 @@ def test_get_bool_value(): assert result is False -def test_get_float_value(): +def test_get_float_value_from_float(): + """ + This test is to ensure that the get_float_value method returns a float when the value is a float + """ parse_node = JsonParseNode(44.6) result = parse_node.get_float_value() + assert isinstance(result, float) assert result == 44.6 +@pytest.mark.parametrize("value", [0, 10, 100]) +def test_get_float_value(value: int): + """ + Consider an OpenAPI Specification using the type: number and format: float or double + Note: The OpenAPI Specification also allows for the use of the type: integer and format: int32 or int64 + + Consider an API with Price data [0, 0.5, 1, 1.5, 2] and so on + In this case, the contract must define the type as a number, with a hint of float or double as the format + + Kiota should be able to parse the response as a float, even if the value is an integer, because it's still a number. + """ + parse_node = JsonParseNode(value) + result = parse_node.get_float_value() + assert isinstance(result, float) + assert result == float(value) + def test_get_uuid_value(): parse_node = JsonParseNode("f58411c7-ae78-4d3c-bb0d-3f24d948de41") result = parse_node.get_uuid_value() From 04220acb9e67a749a74262f3703cc638aae6c0f8 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 26 Jul 2024 09:06:32 -0400 Subject: [PATCH 2/2] chore: adds changelog entry for float fix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46f976f..85cf7a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Fixed a bug where date time deserialization would fail because of empty strings. +- Fixed a bug where float deserialization if the number represented qualified as an int. ## [1.2.0] - 2024-04-09